From 8d7ee0179ad1432bdc94e8b7d45c93d1d79584ad Mon Sep 17 00:00:00 2001 From: Bruce Pennypacker Date: Mon, 28 Oct 2013 19:58:53 +0000 Subject: [PATCH 1/3] Added -r parameter to choose alternate regions. Fixed qty_ calculations to deal with 0 values() --- ec2-check-reserved-instances.py | 41 +++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/ec2-check-reserved-instances.py b/ec2-check-reserved-instances.py index d9c5b5e..c6a025a 100755 --- a/ec2-check-reserved-instances.py +++ b/ec2-check-reserved-instances.py @@ -3,12 +3,36 @@ import sys import os import boto +import boto.ec2 from pprint import pprint +import argparse +from argparse import RawTextHelpFormatter + +AWS_REGIONS = ['ap-northeast-1', + 'ap-southeast-1', + 'ap-southeast-2', + 'eu-west-1', + 'sa-east-1', + 'us-east-1', + 'us-west-1', + 'us-west-2'] # You can uncomment and set these, or set the env variables AWSAccessKeyId & AWSSecretKey # AWS_ACCESS_KEY_ID="aaaaaaaaaaaaaaaaaaaa" # AWS_SECRET_ACCESS_KEY="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" +regiontxt = "If not specified then region us-east-1 is used.\nAvailable regions:\n\n %s" % ( "\n ".join(AWS_REGIONS)) + +parser = argparse.ArgumentParser(description='List a summary of AWS EC2 reservations', epilog=regiontxt, formatter_class=RawTextHelpFormatter) +parser.add_argument('-r', '--region', help="EC2 region name", required=False) +args = parser.parse_args() + +if args.region is not None: + if not args.region in AWS_REGIONS: + print "Unknown region: %s" % ( args.region ) + sys.exit(-1) + + try: AWS_ACCESS_KEY_ID except NameError: @@ -19,8 +43,11 @@ print "Please set env variable" sys.exit(1) +if args.region: + ec2_conn = boto.ec2.connect_to_region(args.region, aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY) +else: + ec2_conn = boto.connect_ec2(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) -ec2_conn = boto.connect_ec2(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) reservations = ec2_conn.get_all_instances() running_instances = {} @@ -53,7 +80,6 @@ # pprint( reserved_instances ) - # this dict will have a positive number if there are unused reservations # and negative number if an instance is on demand instance_diff = dict([(x, reserved_instances[x] - running_instances.get(x, 0 )) for x in reserved_instances]) @@ -81,7 +107,14 @@ for unreserved_instance in unreserved_instances: print "Instance not reserved:\t(%s)\t%s\t%s" % ( unreserved_instances[ unreserved_instance ], unreserved_instance[0], unreserved_instance[1] ) -qty_running_instances = reduce( lambda x, y: x+y, running_instances.values() ) -qty_reserved_instances = reduce( lambda x, y: x+y, reserved_instances.values() ) +if running_instances.values(): + qty_running_instances = reduce( lambda x, y: x+y, running_instances.values() ) +else: + qty_running_instances = 0 + +if reserved_instances.values(): + qty_reserved_instances = reduce( lambda x, y: x+y, reserved_instances.values() ) +else: + qty_reserved_instances = 0 print "\n(%s) running on-demand instances\n(%s) reservations" % ( qty_running_instances, qty_reserved_instances ) From c84087191b5e88912b0bdece1a3dd4b67ee0f83a Mon Sep 17 00:00:00 2001 From: Bruce Pennypacker Date: Tue, 29 Oct 2013 15:28:48 +0000 Subject: [PATCH 2/3] added -n parameter to display the names or ID's of instances that match non-reserved types --- ec2-check-reserved-instances.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ec2-check-reserved-instances.py b/ec2-check-reserved-instances.py index c6a025a..571f5dd 100755 --- a/ec2-check-reserved-instances.py +++ b/ec2-check-reserved-instances.py @@ -7,6 +7,7 @@ from pprint import pprint import argparse from argparse import RawTextHelpFormatter +from collections import defaultdict AWS_REGIONS = ['ap-northeast-1', 'ap-southeast-1', @@ -25,6 +26,7 @@ parser = argparse.ArgumentParser(description='List a summary of AWS EC2 reservations', epilog=regiontxt, formatter_class=RawTextHelpFormatter) parser.add_argument('-r', '--region', help="EC2 region name", required=False) +parser.add_argument('-n', '--names', help="Include names or instance IDs of instances that fit non-reservations", required=False, action='store_true') args = parser.parse_args() if args.region is not None: @@ -51,6 +53,7 @@ reservations = ec2_conn.get_all_instances() running_instances = {} +instance_ids = defaultdict(list) for reservation in reservations: for instance in reservation.instances: if instance.state != "running": @@ -65,6 +68,10 @@ instance_type = instance.instance_type running_instances[ (instance_type, az ) ] = running_instances.get( (instance_type, az ) , 0 ) + 1 + if "Name" in instance.tags and len(instance.tags['Name']) > 0: + instance_ids[ (instance_type, az ) ].append(instance.tags['Name']) + else: + instance_ids[ (instance_type, az ) ].append(instance.id) # pprint( running_instances ) @@ -104,8 +111,11 @@ if unreserved_instances == {}: print "Congratulations, you have no unreserved instances" else: + ids="" for unreserved_instance in unreserved_instances: - print "Instance not reserved:\t(%s)\t%s\t%s" % ( unreserved_instances[ unreserved_instance ], unreserved_instance[0], unreserved_instance[1] ) + if args.names is not None: + ids = ', '.join(sorted(instance_ids[unreserved_instance])) + print "Instance not reserved:\t(%s)\t%s\t%s\t%s" % ( unreserved_instances[ unreserved_instance ], unreserved_instance[0], unreserved_instance[1], ids ) if running_instances.values(): qty_running_instances = reduce( lambda x, y: x+y, running_instances.values() ) From afd6368ce149e997d05b4178ac30bf71d374cc49 Mon Sep 17 00:00:00 2001 From: Bruce Pennypacker Date: Fri, 22 Nov 2013 15:08:02 +0000 Subject: [PATCH 3/3] fixed names check --- ec2-check-reserved-instances.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ec2-check-reserved-instances.py b/ec2-check-reserved-instances.py index 571f5dd..4f1cfef 100755 --- a/ec2-check-reserved-instances.py +++ b/ec2-check-reserved-instances.py @@ -113,7 +113,7 @@ else: ids="" for unreserved_instance in unreserved_instances: - if args.names is not None: + if args.names: ids = ', '.join(sorted(instance_ids[unreserved_instance])) print "Instance not reserved:\t(%s)\t%s\t%s\t%s" % ( unreserved_instances[ unreserved_instance ], unreserved_instance[0], unreserved_instance[1], ids )