Esempio n. 1
0
regions = bc.filter_regions(boto.sns.regions(), args.region)

# execute business logic
log.info("Describing SNS topics:")

if args.topic:
    iam = boto.connect_iam(**credentials)
for region in regions:
    try:
        sns = boto.connect_sns(region=region, **credentials)

        subscriptions = []
        next_token = None
        while True:
            if not args.topic:
                result = sns.get_all_subscriptions(next_token)
                subscriptions.extend(result['ListSubscriptionsResponse']['ListSubscriptionsResult']['Subscriptions'])
                next_token = result['ListSubscriptionsResponse']['ListSubscriptionsResult']['NextToken']
            else:
                arn = bc.create_arn(iam, 'sns', region.name, args.topic)
                result = sns.get_all_subscriptions_by_topic(arn, next_token)
                subscriptions.extend(result['ListSubscriptionsByTopicResponse']['ListSubscriptionsByTopicResult']['Subscriptions'])
                next_token = result['ListSubscriptionsByTopicResponse']['ListSubscriptionsByTopicResult']['NextToken']
            if not next_token:
                break
        print region.name + ": " + str(len(subscriptions)) + " subscriptions"
        for subscription in subscriptions:
            if args.verbose:
                pprint(subscription)
            else:
                print subscription['Endpoint']
Esempio n. 2
0
def alarmProcessor():
    
	# Firstly we need to connect to the Simple Notification Service and CloudWatch service - this was a bit tricky and again the documentation was unclear.  I thought you would use boto.connect_sns(region=reg) 
	# which seems to successfully connect and is similar to how we connected to S3 and EC2 services.  However calling methods e.g. get_all_topics() yields the error "The requested version (2010-03-31) of 
	# service AmazonEC2 does not exist".  On further investigation I found that to connect use boto.sns.connect_to_region().  You have to supply the region as an argument - note that it expected a string 
	# not a region object - which again is inconsistent with EC2. To connect to the CloudWatch service as with SNS you have to use the connect_to_region() method
    sns = boto.sns.connect_to_region("eu-west-1")
    cw = boto.ec2.cloudwatch.connect_to_region("eu-west-1")
    
    if (not args.clear):
        print "\nCreating new topics (+ subscription) and alarms:\n"
        # Once connected we create a topic which is basically an access point composed of an identifier and recipients to send message to. create_topic() returns a unique ARN (Amazon Resource Name) which
        # will include the service name (SNS), region, AWS ID of the user and the topic name - this is a dict so we need to go three levels in to get the actual ARN number.  We will use the arn when
        # we create a subscription which is how we link a topic to an endpoint like an email address.

        topicName = 'TopicStephenCIT-1-UID'+str(random.randrange(1000000))
        response = sns.create_topic(topicName)
        topicARN = response['CreateTopicResponse']['CreateTopicResult']['TopicArn']
        
        print '\tTopic ARN created: ',topicARN
		
		#Subscribe links a topic with an endpoint - in this case an email address
        sns.subscribe(topicARN, 'email',  args.email)

        #We now have topic/subscription - the email address supplied will have to accept the AWS Notification Subscription Confirmation‏ email message to ensure they get alerts
        # We will now create a unique alarm per instance.  We can use the create_alarm method which expects a  boto.ec2.cloudwatch.alarm.MetricAlarm object.  This object defines 
		# all the properties of the alarm - name,metric,topic etc. We loop through all the instance and create an alarm for each instance.  Note we use the ARN that was created 
		# above which ties the alarm to notification logic
                                                   
        for index, inst in enumerate(instances):
            alarmName = "StephenMurrayCPU-" + str(index) + inst.id +'-UID' + str(random.randrange(1000000))
            alarm = boto.ec2.cloudwatch.MetricAlarm(name=alarmName, namespace='AWS/EC2',metric='CPUUtilization',
                                                    statistic='Average',comparison='<', threshold='40',period='60', evaluation_periods=2,
                                                    dimensions = {"InstanceId": inst.id},
                                                    alarm_actions= topicARN)
            cw.create_alarm(alarm)
            print "\tAlarm created", alarmName
    
    else:
        print "\nClearing topics, subscriptions (confirmed) and alarms:\n"
        
        #Get all topics
        returnAllTopicsObject = sns.get_all_topics()
        #to access the ARN field we need have to go 3 levels deep into returned object
        topics = returnAllTopicsObject['ListTopicsResponse']['ListTopicsResult']['Topics']

        #now we have a list containing dicts where the only value is the TopicArn which is what we need to supply the delete method
        # only do action if list is not empty - there has to be some topics to delete
        if topics:
            for t in (topics):
                topicARNDelete = t['TopicArn']
                #delete topics
                sns.delete_topic(topicARNDelete)
                print "\tTopic Deleted: ", topicARNDelete
        else:
            print "\tNo topics found"

        # Get all subscriptions
        # Very similar to topics - get subscriptions, extract relevant parameter from retuned dict object, loop through, get SubscriptionArn
        # and send for deletion - also do a check to ensure subscriptions exist

        returnAllSubObject = sns.get_all_subscriptions()
        #to access the Sub ARN field we need have to go 3 levels deep into returned object
        subscriptions = returnAllSubObject['ListSubscriptionsResponse']['ListSubscriptionsResult']['Subscriptions']

        if subscriptions:
            for s in (subscriptions):
                subARNDelete = s['SubscriptionArn']
                #delete subscription only if returned value is not equal to PendingConfirmation
                if (subARNDelete != 'PendingConfirmation'):
                    sns.unsubscribe(subARNDelete)
                    print "\tSunscription Deleted: ", subARNDelete
        else:
            print "\tNo subscriptions found"

        #Get all alarms
        #describe_alarms() returns a list of boto.ec2.cloudwatch.alarm.MetricAlarms object from which we can extract the alarm name (.name method) which we can
        # use to delete it - Note in this case we do not require the ARN to delete - on testing with IDLE it was noted that when a complete arn
        # arn:aws:cloudwatch:eu-west-1:135577527805:alarm:StephenMurrayCPU0i-690b332b was supplied the delete_alarms() method returned True even though it was
        # not deleted...this is not good as as when StephenMurrayCPU0i-690b332b was supplied it deleted the alarm and also returned True.

        alarms = cw.describe_alarms()
        if alarms:
            for a in (alarms):
                cw.delete_alarms(a.name)
                print "\tAlarms Deleted: ", a.name
        else:
            print "\tNo alarms found"