def main():
    parser = optparse.OptionParser('Usage: %prog <options>')
    parser.add_option('-e', '--email', dest='email',
        help='The email address to send notifications to whenever an '
             'alert is triggered.')
    parser.add_option('-n', '--name', dest='name',
        help='The name of the alarm (e.g., BillingAlarm-1000).')
    parser.add_option('-t', '--threshold', dest='threshold',
        help='The dollar amount of estimated monthly charges which, '
             'when exceeded, causes an alert to be triggered.')
    parser.add_option('-p', '--period', dest='period', default=Defaults.PREIOD,
        help='The period in seconds over which the estimated monthly '
             'charges statistic is applied.')
    (opts, args) = parser.parse_args()

    if (0 != len(args) or
        opts.email is None or
        opts.threshold is None):
        parser.print_help()
        return 1

    try:
        sns = boto.connect_sns()

        topic = sns.create_topic('BillingNotifications') \
            ['CreateTopicResponse'] \
            ['CreateTopicResult'] \
            ['TopicArn']

        res = sns.subscribe(topic, 'email', opts.email) \
            ['SubscribeResponse'] \
            ['SubscribeResult'] \
            ['SubscriptionArn']
        if res == 'pending confirmation':
            raw_input('Please confirm subscription. Press [ENTER] when done...')

        cloudwatch = boto.connect_cloudwatch()

        alarm = MetricAlarm(name=opts.name if opts.name is not None
                else 'BillingAlarm-{0}'.format(opts.threshold),
            description='Estimated Monthly Charges',
            alarm_actions=[topic],
            metric=Defaults.METRIC,
            namespace='AWS/Billing',
            statistic=Defaults.STATISTIC,
            dimensions={'Currency':'USD'},
            period=opts.period,
            evaluation_periods=1,
            threshold=int(opts.threshold),
            comparison='>=')
        cloudwatch.create_alarm(alarm)
    except Error, err:
        sys.stderr.write('[ERROR] {0}\n'.format(err))
        return 1
Example #2
0
 def cw_alarm(self, cw_conn, instance_id, email_add):
     """ Create cloudwatch alarm on an instance when CPU utilisation is less
     than or equal to 40% for five minutes, and send sns alert to an email address """
     sns = boto.sns.connect_to_region('eu-west-1')
     topic_name = 'cpu_alarm'+instance_id
     new_sns_topic = sns.create_topic(topic_name)
     sns_arn = self.get_sns_arn(new_sns_topic)
     sns.subscribe(sns_arn, 'email', email_add)
     metrics = cw_conn.list_metrics(dimensions={'InstanceId': instance_id}, metric_name="CPUUtilization")
     ec2_alarm = metrics[0].create_alarm(name=topic_name, comparison='<=', threshold=40.0, period=300,
                                         evaluation_periods=2, statistic='Average', alarm_actions=[sns_arn])
     if ec2_alarm:
         print 'cloudwatch alarm created'
def create_alarm(instance_id):
	global alarmed
	if alarmed == False:
	    sns = boto.sns.connect_to_region('eu-west-1')
	    sns.create_topic('DavidK_Network_Problem') # Create a topic
	    arn = 'arn:aws:sns:eu-west-1:808146113457:DavidK_Network_Problem' #Amazon Resource Name, uniquely identify AWS resources
	    sns.subscribe(arn, "email", "*****@*****.**") # subscribe my email to the topic

	    cloudwatch = boto.ec2.cloudwatch.connect_to_region('eu-west-1')
	    # create a list holding the metric that the alarm will be based on
	    metrics = cloudwatch.list_metrics(dimensions={'InstanceId' : instance_id},metric_name='NetworkIn')
	    # call to create the autoscaling group and to get policy arn for the alarm
	    as_policy_arn = create_auto_scaling(instance_id)
	    # create the alarm
	    alarm = metrics[0].create_alarm(name='Network_Usage_Alarm', comparison='>=', threshold=500000, period=60,
                    evaluation_periods=1, statistic='Average', alarm_actions=[arn,as_policy_arn])
	    if alarm:
	    	print '\n----------'
		    print 'Alarm set'
		    print '----------\n'
		    alarmed = True
	    else:
		    print '\nAlarm has not been set\n'
for aws_region in regions:
    if aws_region in ['cn-north-1', 'us-gov-west-1']:
        logging.debug('Ignoring restricted region: ' + aws_region)
    else:
        logging.info(
            '********************************************************************************'
        )
        logging.info(' Starting to create CloudTrail resources in region: ' +
                     aws_region)
        if arguments['--generate_topics']:
            logging.info('Generating topic for CloudTrail in region: ' +
                         aws_region)
            sns = boto.sns.connect_to_region(aws_region)
            logging.debug('Connected to SNS API in region: ' + aws_region)
            arguments['topic_name'] = sns.create_topic(
                arguments['--topic_name']
            )['CreateTopicResponse']['CreateTopicResult']['TopicArn']

        ct = boto.cloudtrail.connect_to_region(aws_region)
        logging.debug('Connected to CloudTrail API in region: ' + aws_region)
        if len(
                ct.describe_trails(
                    trail_name_list=[arguments.get('--trail_name', 'Default')
                                     ]).get('trailList', [])) == 0:
            logging.info('Creating new trail in region ' + aws_region)
            ct.create_trail(name=arguments.get('--trail_name', 'Default'),
                            s3_bucket_name=output_variables.get(
                                'bucketName', ''),
                            s3_key_prefix=arguments.get('--s3_key_prefix'),
                            sns_topic_name=arguments.get('topic_name'),
                            include_global_service_events=global_logging)
Example #5
0
parser.add_argument("topic", help="A topic name")
parser.add_argument(
    "-d",
    "--display_name",
    help=
    "Override the topics display name (will get region suffix) [default: topic name]"
)
args = parser.parse_args()

# process common command line arguments
log = logging.getLogger('botocross')
bc.configure_logging(log, args.log_level)
credentials = bc.parse_credentials(args)
regions = bc.filter_regions(boto.sns.regions(), args.region)

# execute business logic
log.info("Creating SNS topics named '" + args.topic + "':")

for region in regions:
    pprint(region.name, indent=2)
    try:
        sns = boto.connect_sns(region=region, **credentials)
        topic = sns.create_topic(args.topic)
        arn = topic['CreateTopicResponse']['CreateTopicResult']['TopicArn']
        print arn
        display_name = args.display_name if args.display_name else args.topic
        display_name += '-' + region.name
        sns.set_topic_attributes(arn, 'DisplayName', display_name)
    except boto.exception.BotoServerError, e:
        log.error(e.error_message)
logging.debug('Regions:' + json.dumps(regions))

global_logging = True

for aws_region in regions:
    if aws_region in ['cn-north-1', 'us-gov-west-1']:
        logging.debug('Ignoring restricted region: ' + aws_region)
    else:
        logging.info('********************************************************************************')
        logging.info(' Starting to create CloudTrail resources in region: ' + aws_region)
        if arguments['--generate_topics']:
            logging.info('Generating topic for CloudTrail in region: ' + aws_region)
            sns = boto.sns.connect_to_region(aws_region)
            logging.debug('Connected to SNS API in region: ' + aws_region)
            arguments['topic_name'] = sns.create_topic(arguments['--topic_name'])['CreateTopicResponse']['CreateTopicResult']['TopicArn']

        ct = boto.cloudtrail.connect_to_region(aws_region)
        logging.debug('Connected to CloudTrail API in region: ' + aws_region)
        if len(ct.describe_trails(trail_name_list=[arguments.get('--trail_name', 'Default')]).get('trailList',[])) == 0:
            logging.info('Creating new trail in region ' + aws_region)
            ct.create_trail(name=arguments.get('--trail_name', 'Default'), s3_bucket_name=output_variables.get('bucketName', ''), s3_key_prefix=arguments.get('--s3_key_prefix'), sns_topic_name=arguments.get('topic_name'), include_global_service_events=global_logging)
            ct.start_logging(name=arguments.get('--trail_name', 'Default'))
            if global_logging == True:
              global_logging = False
        elif ct.get_trail_status('Default').get('IsLogging') == False:
            logging.info('Updating Trail in region ' + aws_region)
            ct.update_trail(name=arguments.get('--trail_name', 'Default'), s3_bucket_name=output_variables.get('bucketName', ''), s3_key_prefix=arguments.get('--s3_key_prefix'), sns_topic_name=arguments.get('topic_name'), include_global_service_events=global_logging)
            if global_logging == True:
              global_logging = False
            ct.start_logging(name=arguments.get('--trail_name', 'Default'))
parser.add_argument("--access_key_id", dest='aws_access_key_id', help="Your AWS Access Key ID")
parser.add_argument("--secret_access_key", dest='aws_secret_access_key', help="Your AWS Secret Access Key")
args = parser.parse_args()

credentials = {'aws_access_key_id': args.aws_access_key_id, 'aws_secret_access_key': args.aws_secret_access_key}

def isSelected(region):
    return True if region.name.find(args.region) != -1 else False

# execute business logic
heading = "Creating SNS topics named '" + args.topic + "'"
regions = boto.sns.regions()
if args.region:
    heading += " (filtered by region '" + args.region + "')"
    regions = filter(isSelected, regions)

print heading + ":"
for region in regions:
    pprint(region.name, indent=2)
    try:
        sns = boto.connect_sns(region=region, **credentials)
        print 'Creating topic ' + args.topic
        topic = sns.create_topic(args.topic)
        arn = topic['CreateTopicResponse']['CreateTopicResult']['TopicArn']
        print('... topic ARN is ' + arn)
        display_name = args.display_name if args.display_name else args.topic
        display_name += '-' + region.name
        sns.set_topic_attributes(arn, 'DisplayName', display_name)
    except boto.exception.BotoServerError, e:
        print e.error_message
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"
Example #9
0
def main():
    parser = optparse.OptionParser('Usage: %prog <options>')
    parser.add_option(
        '-e',
        '--email',
        dest='email',
        help='The email address to send notifications to whenever an '
        'alert is triggered.')
    parser.add_option('-n',
                      '--name',
                      dest='name',
                      help='The name of the alarm (e.g., BillingAlarm-1000).')
    parser.add_option(
        '-t',
        '--threshold',
        dest='threshold',
        help='The dollar amount of estimated monthly charges which, '
        'when exceeded, causes an alert to be triggered.')
    parser.add_option(
        '-p',
        '--period',
        dest='period',
        default=Defaults.PREIOD,
        help='The period in seconds over which the estimated monthly '
        'charges statistic is applied.')
    (opts, args) = parser.parse_args()

    if (0 != len(args) or opts.email is None or opts.threshold is None):
        parser.print_help()
        return 1

    try:
        sns = boto.connect_sns()

        topic = sns.create_topic('BillingNotifications') \
            ['CreateTopicResponse'] \
            ['CreateTopicResult'] \
            ['TopicArn']

        res = sns.subscribe(topic, 'email', opts.email) \
            ['SubscribeResponse'] \
            ['SubscribeResult'] \
            ['SubscriptionArn']
        if res == 'pending confirmation':
            raw_input(
                'Please confirm subscription. Press [ENTER] when done...')

        cloudwatch = boto.connect_cloudwatch()

        alarm = MetricAlarm(name=opts.name if opts.name is not None else
                            'BillingAlarm-{0}'.format(opts.threshold),
                            description='Estimated Monthly Charges',
                            alarm_actions=[topic],
                            metric=Defaults.METRIC,
                            namespace='AWS/Billing',
                            statistic=Defaults.STATISTIC,
                            dimensions={'Currency': 'USD'},
                            period=opts.period,
                            evaluation_periods=1,
                            threshold=int(opts.threshold),
                            comparison='>=')
        cloudwatch.create_alarm(alarm)
    except Error, err:
        sys.stderr.write('[ERROR] {0}\n'.format(err))
        return 1