Allow SNS topics to be created without subscriptions. Also added better error handling around boto calls.
This commit is contained in:
parent
b51efc51bc
commit
ce9aed9c52
1 changed files with 52 additions and 23 deletions
|
@ -132,8 +132,8 @@ import json
|
|||
import re
|
||||
|
||||
try:
|
||||
import boto
|
||||
import boto.sns
|
||||
from boto.exception import BotoServerError
|
||||
HAS_BOTO = True
|
||||
except ImportError:
|
||||
HAS_BOTO = False
|
||||
|
@ -146,12 +146,15 @@ def canonicalize_endpoint(protocol, endpoint):
|
|||
return endpoint
|
||||
|
||||
|
||||
|
||||
def get_all_topics(connection):
|
||||
def get_all_topics(connection, module):
|
||||
next_token = None
|
||||
topics = []
|
||||
while True:
|
||||
try:
|
||||
response = connection.get_all_topics(next_token)
|
||||
except BotoServerError, e:
|
||||
module.fail_json(msg=e.message)
|
||||
|
||||
topics.extend(response['ListTopicsResponse']['ListTopicsResult']['Topics'])
|
||||
next_token = \
|
||||
response['ListTopicsResponse']['ListTopicsResult']['NextToken']
|
||||
|
@ -160,15 +163,16 @@ def get_all_topics(connection):
|
|||
return [t['TopicArn'] for t in topics]
|
||||
|
||||
|
||||
def arn_topic_lookup(connection, short_topic):
|
||||
def arn_topic_lookup(connection, short_topic, module):
|
||||
# topic names cannot have colons, so this captures the full topic name
|
||||
all_topics = get_all_topics(connection)
|
||||
all_topics = get_all_topics(connection, module)
|
||||
lookup_topic = ':%s' % short_topic
|
||||
for topic in all_topics:
|
||||
if topic.endswith(lookup_topic):
|
||||
return topic
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
argument_spec = ec2_argument_spec()
|
||||
argument_spec.update(
|
||||
|
@ -179,7 +183,7 @@ def main():
|
|||
display_name=dict(type='str', required=False),
|
||||
policy=dict(type='dict', required=False),
|
||||
delivery_policy=dict(type='dict', required=False),
|
||||
subscriptions=dict(type='list', required=False),
|
||||
subscriptions=dict(default=[], type='list', required=False),
|
||||
purge_subscriptions=dict(type='bool', default=True),
|
||||
)
|
||||
)
|
||||
|
@ -214,7 +218,7 @@ def main():
|
|||
|
||||
# topics cannot contain ':', so thats the decider
|
||||
if ':' in name:
|
||||
all_topics = get_all_topics(connection)
|
||||
all_topics = get_all_topics(connection, module)
|
||||
if name in all_topics:
|
||||
arn_topic = name
|
||||
elif state == 'absent':
|
||||
|
@ -223,7 +227,7 @@ def main():
|
|||
module.fail_json(msg="specified an ARN for a topic but it doesn't"
|
||||
" exist")
|
||||
else:
|
||||
arn_topic = arn_topic_lookup(connection, name)
|
||||
arn_topic = arn_topic_lookup(connection, name, module)
|
||||
if not arn_topic:
|
||||
if state == 'absent':
|
||||
module.exit_json(changed=False)
|
||||
|
@ -234,15 +238,22 @@ def main():
|
|||
|
||||
changed=True
|
||||
topic_created = True
|
||||
try:
|
||||
connection.create_topic(name)
|
||||
arn_topic = arn_topic_lookup(connection, name)
|
||||
except BotoServerError, e:
|
||||
module.fail_json(msg=e.message)
|
||||
arn_topic = arn_topic_lookup(connection, name, module)
|
||||
while not arn_topic:
|
||||
time.sleep(3)
|
||||
arn_topic = arn_topic_lookup(connection, name)
|
||||
arn_topic = arn_topic_lookup(connection, name, module)
|
||||
|
||||
if arn_topic and state == "absent":
|
||||
if not check_mode:
|
||||
try:
|
||||
connection.delete_topic(arn_topic)
|
||||
except BotoServerError, e:
|
||||
module.fail_json(msg=e.message)
|
||||
|
||||
module.exit_json(changed=True)
|
||||
|
||||
topic_attributes = connection.get_topic_attributes(arn_topic) \
|
||||
|
@ -252,30 +263,40 @@ def main():
|
|||
changed = True
|
||||
attributes_set.append('display_name')
|
||||
if not check_mode:
|
||||
connection.set_topic_attributes(arn_topic, 'DisplayName',
|
||||
display_name)
|
||||
try:
|
||||
connection.set_topic_attributes(arn_topic, 'DisplayName', display_name)
|
||||
except BotoServerError, e:
|
||||
module.fail_json(msg=e.message)
|
||||
|
||||
if policy and policy != json.loads(topic_attributes['policy']):
|
||||
changed = True
|
||||
attributes_set.append('policy')
|
||||
if not check_mode:
|
||||
connection.set_topic_attributes(arn_topic, 'Policy',
|
||||
json.dumps(policy))
|
||||
try:
|
||||
connection.set_topic_attributes(arn_topic, 'Policy', json.dumps(policy))
|
||||
except BotoServerError, e:
|
||||
module.fail_json(msg=e.message)
|
||||
|
||||
if delivery_policy and ('DeliveryPolicy' not in topic_attributes or \
|
||||
delivery_policy != json.loads(topic_attributes['DeliveryPolicy'])):
|
||||
changed = True
|
||||
attributes_set.append('delivery_policy')
|
||||
if not check_mode:
|
||||
connection.set_topic_attributes(arn_topic, 'DeliveryPolicy',
|
||||
json.dumps(delivery_policy))
|
||||
try:
|
||||
connection.set_topic_attributes(arn_topic, 'DeliveryPolicy',json.dumps(delivery_policy))
|
||||
except BotoServerError, e:
|
||||
module.fail_json(msg=e.message)
|
||||
|
||||
|
||||
next_token = None
|
||||
aws_subscriptions = []
|
||||
while True:
|
||||
try:
|
||||
response = connection.get_all_subscriptions_by_topic(arn_topic,
|
||||
next_token)
|
||||
except BotoServerError, e:
|
||||
module.fail_json(msg=e.message)
|
||||
|
||||
aws_subscriptions.extend(response['ListSubscriptionsByTopicResponse'] \
|
||||
['ListSubscriptionsByTopicResult']['Subscriptions'])
|
||||
next_token = response['ListSubscriptionsByTopicResponse'] \
|
||||
|
@ -286,6 +307,7 @@ def main():
|
|||
desired_subscriptions = [(sub['protocol'],
|
||||
canonicalize_endpoint(sub['protocol'], sub['endpoint'])) for sub in
|
||||
subscriptions]
|
||||
|
||||
aws_subscriptions_list = []
|
||||
|
||||
for sub in aws_subscriptions:
|
||||
|
@ -296,14 +318,20 @@ def main():
|
|||
changed = True
|
||||
subscriptions_deleted.append(sub_key)
|
||||
if not check_mode:
|
||||
try:
|
||||
connection.unsubscribe(sub['SubscriptionArn'])
|
||||
except BotoServerError, e:
|
||||
module.fail_json(msg=e.message)
|
||||
|
||||
for (protocol, endpoint) in desired_subscriptions:
|
||||
if (protocol, endpoint) not in aws_subscriptions_list:
|
||||
changed = True
|
||||
subscriptions_added.append(sub)
|
||||
if not check_mode:
|
||||
try:
|
||||
connection.subscribe(arn_topic, protocol, endpoint)
|
||||
except BotoServerError, e:
|
||||
module.fail_json(msg=e.message)
|
||||
|
||||
module.exit_json(changed=changed, topic_created=topic_created,
|
||||
attributes_set=attributes_set,
|
||||
|
@ -313,4 +341,5 @@ def main():
|
|||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.ec2 import *
|
||||
|
||||
main()
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
Loading…
Reference in a new issue