Skip to content

Commit

Permalink
Fetch the savings plan detials from AWS inventory (#753)
Browse files Browse the repository at this point in the history
  • Loading branch information
athiruma authored Apr 16, 2024
1 parent 0941908 commit 34cc845
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from datetime import datetime
from datetime import datetime, timedelta

import boto3
from dateutil.relativedelta import relativedelta

from cloud_governance.common.utils.configs import HOURS_IN_SECONDS, HOURS_IN_DAY


class SavingsPlansOperations:
"""
Expand Down Expand Up @@ -63,13 +65,15 @@ def get_savings_filter_data(self, savings_plans_list: list = None):
responses.append(monthly_savings_data)
return responses

def get_savings_plans_list(self, states: list = [], **kwargs):
def get_savings_plans_list(self, states: list = None, **kwargs):
"""
This method returns the savings plans list
:param states:
:return:
"""
results = {}
if not states:
states = ['active']
kwargs.update({'states': states})
if not kwargs.get('states'):
kwargs.pop('states')
Expand All @@ -79,3 +83,50 @@ def get_savings_plans_list(self, states: list = [], **kwargs):
response = self.savings_plan_client.describe_savings_plans(**kwargs)
results[self.SAVINGS_PLANS].append(response.get(self.SAVINGS_PLANS))
return results[self.SAVINGS_PLANS]

def get_monthly_active_savings_plan_summary(self):
"""
This method returns the monthly savings plans summary
:return:
:rtype:
"""
savings_plans = self.get_savings_plans_list()
monthly_sp_sum = {}
for sp in savings_plans:
start_date = datetime.fromisoformat(sp.get('start')[:-1])
end_date = datetime.fromisoformat(sp.get('end')[:-1])
commitment = float(sp.get('commitment', 0))
monthly_commitments = self.__get_monthly_commitments(start_date=start_date, end_date=end_date,
commitment=commitment)
for month, monthly_commitment in monthly_commitments.items():
monthly_sp_sum[month] = monthly_sp_sum.get(month, 0) + monthly_commitment
return monthly_sp_sum

def __get_monthly_commitments(self, start_date: datetime, end_date: datetime, commitment: float):
"""
This method split the date rages to months
:param start_date:
:type start_date:
:param end_date:
:type end_date:
:return:
:rtype:
"""
current_month = start_date
monthly_ranges = {}
while current_month <= end_date:
month = current_month.month % 12 + 1
year = current_month.year
if current_month.month % 12 == 0:
year = current_month.year + 1
month = 1
end_of_month = current_month.replace(year=year, month=month, day=1) - timedelta(days=1)
end_of_month = min(end_of_month, end_date)
total_seconds = (end_of_month - current_month).total_seconds()
monthly_commitment = commitment * ((total_seconds / HOURS_IN_SECONDS) + HOURS_IN_DAY)
monthly_ranges[str(current_month.date().replace(day=1))] = monthly_commitment
if current_month.month == 12:
current_month = datetime(current_month.year + 1, 1, 1)
else:
current_month = datetime(current_month.year, current_month.month + 1, 1)
return monthly_ranges
3 changes: 3 additions & 0 deletions cloud_governance/common/utils/configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
MONTHS = 12
DEFAULT_ROUND_DIGITS = 3
PUBLIC_ACCOUNTS_COST_REPORTS = 'Accounts'
HOURS_IN_SECONDS = 3600
HOURS_IN_DAY = 24


DATE_FORMAT = "%Y-%m-%d"
DATE_TIME_FORMAT_T = "%Y-%m-%dT%h:%m"
UNUSED_DAYS = 7
6 changes: 4 additions & 2 deletions cloud_governance/policy/aws/cost_explorer_payer_billings.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class CostExplorerPayerBillings(CostBillingReports):

def __init__(self):
super().__init__()
self.__savings_plan_list = None
self.__aws_role = self._environment_variables_dict.get("AWS_ACCOUNT_ROLE")
self.__access_key, self.__secret_key, self.__session = self.__get_sts_credentials()
self.__ce_client = boto3.client('ce', aws_access_key_id=self.__access_key, aws_secret_access_key=self.__secret_key, aws_session_token=self.__session)
Expand Down Expand Up @@ -71,7 +72,7 @@ def filter_data_by_tag(self, cost_data: dict, tag: str, cost_center: int = ''):
timestamp = datetime.datetime.strptime(start_time, '%Y-%m-%d')
month = datetime.datetime.strftime(timestamp, "%Y %b")
month_full_name = datetime.datetime.strftime(timestamp, "%B")
payer_monthly_savings_plan = self.update_to_gsheet.get_monthly_spa(month_name=month_full_name, dir_path=self.__temporary_dir)
payer_monthly_savings_plan = self.__savings_plan_list[start_time]
budget = account_budget if start_time.split('-')[0] in years else 0
index_id = f'{start_time}-{name}'
upload_data = {tag: name, 'Actual': round(float(amount), self.DEFAULT_ROUND_DIGITS), 'start_date': start_time,
Expand Down Expand Up @@ -111,7 +112,7 @@ def filter_forecast_data(self, cost_forecast_data: list, cost_usage_data: dict,
index = f'{start_date}-{account_id}'
month_full_name = datetime.datetime.strftime(datetime.datetime.strptime(start_date, '%Y-%m-%d'), "%B")
total_percentage = (cost / float(self.__monthly_cost_for_spa_calc.get(start_date)))
payer_monthly_savings_plan = self.update_to_gsheet.get_monthly_spa(month_name=month_full_name, dir_path=self.__temporary_dir)
payer_monthly_savings_plan = self.__savings_plan_list[start_date]
if index in cost_usage_data[account]:
cost_usage_data[account][index]['Forecast'] = cost
cost_usage_data[account][index]['TotalPercentage'] = total_percentage
Expand Down Expand Up @@ -169,6 +170,7 @@ def get_cost_centers(self):
@logger_time_stamp
def get_linked_accounts_usage(self):
"""This method get the linked accounts usage using cost center"""
self.__savings_plan_list = self.__savings_plan_operations.get_monthly_active_savings_plan_summary()
cost_centers = self.get_cost_centers()
cost_usage_data = {}
start_date, end_date = self.get_date_ranges()
Expand Down

0 comments on commit 34cc845

Please sign in to comment.