def aws_underutilized_resources_reduced_cost(accounts): now = datetime.utcnow() date_from = now.replace(hour=0, minute=0, second=0, microsecond=0) - relativedelta(months=6) date_to = now.replace(hour=23, minute=59, second=59, microsecond=999999) resources = AWSMetric.underutilized_resources(account.key for account in accounts) resource_ids = set(r['id'] for r in resources['resources']) months = AWSDetailedLineitem.get_monthly_cost_by_resource(resource_ids, date_from=date_from, date_to=date_to) res = { # Simply multiply every cost by 20% as all instances usage is k: v * 0.2 # less than 20%. TODO: intelligently find the best type for k, v in months.iteritems() } return jsonify(res)
def compute_reservation_forecast(keys): if isinstance(keys, models.AWSKey): keys = [keys] elif not isinstance(keys, list): keys = list(keys) if not all(isinstance(k, models.AWSKey) for k in keys): raise TypeError('All keys must be AWSKey.') now = datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0) range_end = now.replace(hour=0, minute=0, second=0, microsecond=0) range_end -= timedelta(days=1) range_start = range_end - timedelta(days=120) range_start = range_start.replace(day=1) s = AWSDetailedLineitem.get_instance_type( [k.get_aws_user_id() for k in keys], date_from=range_start, date_to=range_end) instance_type_hours = defaultdict(list) first_hour = datetime(2099, 1, 1) for r in s: rhour = datetime.strptime(r['hour'], "%Y-%m-%dT%H:%M:%S") if r['region'] != 'unknown': # Some EC2 instances have no region, sometimes... instance_type_hours[(r['region'], r['instance'])].append( (rhour, r['ridCount'])) first_hour = min(first_hour, rhour) hours_ahead = 120 * 24 total_hours = (range_end - first_hour).total_seconds() / 3600 - 1 + hours_ahead instance_types = [] lookup = get_instance_lookup() for (region, instance_type), hours in instance_type_hours.iteritems(): hours = count_forecast(hours, range_start, now, hours_ahead) prices = lookup[region, instance_type] price_results = get_monthly_prices( total_hours, hours, [p['amortized'] for p in prices['reserved']], prices['ondemand']['amortized']) ps = [] for pricing, (_, count, months) in zip(prices['reserved'] + [prices['ondemand']], price_results): pricing = dict(pricing) if count is not None: pricing['count'] = count pricing['months'] = [ dict(month=m.strftime('%Y-%m'), cost=c) for m, c in months[:-1] ] ps.append(pricing) instance_types.append( dict(region=region, type=instance_type, pricing_options=ps)) available_volumes = AWSStat.latest_available_volumes([k.key for k in keys]) now = datetime.utcnow() date_from = now.replace(hour=0, minute=0, second=0, microsecond=0) - relativedelta(months=6) date_to = now.replace(hour=23, minute=59, second=59, microsecond=999999) volume_monthly_costs = AWSDetailedLineitem.get_monthly_cost_by_resource( available_volumes['volumes'] if 'volumes' in available_volumes else (), date_from=date_from, date_to=date_to) resources = AWSMetric.underutilized_resources([k.key for k in keys]) rids = set(r['id'] for r in resources['resources']) months = AWSDetailedLineitem.get_monthly_cost_by_resource( rids, date_from=date_from, date_to=date_to) reduced_instance_costs = {k: v * 0.2 for k, v in months.iteritems()} return dict( instances=instance_types, volume_monthly_costs=volume_monthly_costs, reduced_instance_costs=reduced_instance_costs, )