From 5bec3d6bf979fef8062759f75b23884c8244c305 Mon Sep 17 00:00:00 2001 From: Gustavo Soares Souza Date: Wed, 4 Sep 2019 17:44:56 +1200 Subject: [PATCH 1/2] logs --- src/check_reserved_instances/calculate.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/check_reserved_instances/calculate.py b/src/check_reserved_instances/calculate.py index ce46ac3..fc3babe 100644 --- a/src/check_reserved_instances/calculate.py +++ b/src/check_reserved_instances/calculate.py @@ -41,7 +41,9 @@ def report_diffs(running_instances, reserved_instances): instance_diff = {} regional_benefit_ris = {} # loop through the reserved instances + print("reserved") for placement_key in reserved_instances: + print placement_key # if the AZ from an RI is 'All' (regional benefit RI) if placement_key[1] == 'All': # put into another dict for these RIs for processing later @@ -52,11 +54,15 @@ def report_diffs(running_instances, reserved_instances): placement_key] - running_instances.get(placement_key, 0) # add unreserved instances to instance_diff + print "running" for placement_key in running_instances: + print placement_key if placement_key not in reserved_instances: instance_diff[placement_key] = -running_instances[ placement_key] + print "running_instances: %s" % running_instances + # loop through regional benefit RI's for ri in regional_benefit_ris: # loop through the entire instace diff From 2eeec8f8802147aa7d2350915058a6b0e57d6c68 Mon Sep 17 00:00:00 2001 From: Gustavo Soares Souza Date: Fri, 6 Sep 2019 16:24:03 +1200 Subject: [PATCH 2/2] add normalisation factor --- src/check_reserved_instances/aws.py | 21 ------- src/check_reserved_instances/calculate.py | 75 ++++++++++++++++++++--- 2 files changed, 68 insertions(+), 28 deletions(-) diff --git a/src/check_reserved_instances/aws.py b/src/check_reserved_instances/aws.py index 41337e9..56c9d1f 100644 --- a/src/check_reserved_instances/aws.py +++ b/src/check_reserved_instances/aws.py @@ -16,27 +16,6 @@ # reserve expiration time to report with unused reservations reserve_expiry = defaultdict(list) -# normalization factor -# https://aws.amazon.com/blogs/aws/new-instance-size-flexibility-for-ec2-reserved-instances/ -NORMALIZATION_FACTOR = { - 'nano': 0.25, - 'micro': 0.5, - 'small': 1, - 'medium': 2, - 'large': 4, - 'xlarge': 8, - '2xlarge': 16, - '4xlarge': 32, - '8xlarge': 64, - '9xlarge': 72, - '10xlarge': 80, - '12xlarge': 96, - '16xlarge': 128, - '18xlarge': 144, - '24xlarge': 192, - '32xlarge': 256, -} - def create_boto_session(account): """Set up the boto3 session to connect to AWS. diff --git a/src/check_reserved_instances/calculate.py b/src/check_reserved_instances/calculate.py index fc3babe..bd0f4e5 100644 --- a/src/check_reserved_instances/calculate.py +++ b/src/check_reserved_instances/calculate.py @@ -2,8 +2,30 @@ from __future__ import absolute_import + import datetime +RI_BASE_INSTANCE_TYPE = 'large' +# normalization factor +# https://aws.amazon.com/blogs/aws/new-instance-size-flexibility-for-ec2-reserved-instances/ +NORMALIZATION_FACTOR = { + 'nano': 0.25, + 'micro': 0.5, + 'small': 1, + 'medium': 2, + 'large': 4, + 'xlarge': 8, + '2xlarge': 16, + '4xlarge': 32, + '8xlarge': 64, + '9xlarge': 72, + '10xlarge': 80, + '12xlarge': 96, + '16xlarge': 128, + '18xlarge': 144, + '24xlarge': 192, + '32xlarge': 256, +} def calc_expiry_time(expiry): """Calculate the number of days until the reserved instance expires. @@ -18,6 +40,35 @@ def calc_expiry_time(expiry): """ return (expiry.replace(tzinfo=None) - datetime.datetime.utcnow()).days +def convert_instance(placement_key, count): + """ + Used to calculate normalisation factor. Converts an instance type to RI_BASE_INSTANCE_TYPE + placement_key is a tuple with the instance type and region: e.g ('c4.2xlarge', 'us-west-2a') + count: is an int + + """ + instance = placement_key[0] + region = placement_key[1] + family, instance_type = instance.split('.') + + # test if it is a t instance type + if instance_type.startswith('t'): + print instance_type + return placement_key, count + + # test if we know the instance type + if instance_type not in NORMALIZATION_FACTOR: + return placement_key, count + + # convert instance to normalised instance + multiplier = NORMALIZATION_FACTOR[instance_type] / NORMALIZATION_FACTOR[RI_BASE_INSTANCE_TYPE] + + normalised_placement_key = ("%s.%s" % (family, RI_BASE_INSTANCE_TYPE)) + normalised_count = multiplier * count + + #print("Normalised placement key -> %s: %s" % (normalised_placement_key, normalised_count)) + return normalised_placement_key, normalised_count + def report_diffs(running_instances, reserved_instances): """Calculate differences between reserved instances and running instances. @@ -38,12 +89,25 @@ def report_diffs(running_instances, reserved_instances): """ + normalised_running_instances = {} instance_diff = {} regional_benefit_ris = {} # loop through the reserved instances + + # normalise instances using normalisation factor + for placement_key, count in running_instances.items(): + print("%s: %s" % (placement_key, count)) + # convert instance type using normalisation factor + normalised_placement_key, normalised_count = convert_instance(placement_key, count) + count_ = normalised_running_instances.get(normalised_placement_key, 0) + normalised_running_instances[normalised_placement_key] = normalised_count + count_ + + print("normalised running instances") + print normalised_running_instances + print("reserved") - for placement_key in reserved_instances: - print placement_key + for placement_key, count in reserved_instances.items(): + print("%s: %s" % (placement_key, count)) # if the AZ from an RI is 'All' (regional benefit RI) if placement_key[1] == 'All': # put into another dict for these RIs for processing later @@ -54,15 +118,12 @@ def report_diffs(running_instances, reserved_instances): placement_key] - running_instances.get(placement_key, 0) # add unreserved instances to instance_diff - print "running" - for placement_key in running_instances: - print placement_key + for placement_key, count in running_instances.items(): + instance_type = placement_key[0] if placement_key not in reserved_instances: instance_diff[placement_key] = -running_instances[ placement_key] - print "running_instances: %s" % running_instances - # loop through regional benefit RI's for ri in regional_benefit_ris: # loop through the entire instace diff