Skip to content

Commit 8140982

Browse files
authored
Merge pull request #86 from ImMin5/master
Add billing account scope logic for MPA
2 parents ec3bcfb + 4483f29 commit 8140982

File tree

4 files changed

+114
-52
lines changed

4 files changed

+114
-52
lines changed

Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM cloudforet/python-core:2.0
1+
FROM cloudforet/python-core:2.0.90
22

33
ENV PYTHONUNBUFFERED 1
44
ENV SPACEONE_PORT 50051

src/cloudforet/cost_analysis/connector/azure_cost_mgmt_connector.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ def query_usage_http(
206206
yield response_json
207207
except Exception as e:
208208
_LOGGER.error(f"[ERROR] query_usage_http {e}", exc_info=True)
209-
raise ERROR_UNKNOWN(message=f"[ERROR] get_usd_cost_and_tag_http {e}")
209+
raise ERROR_UNKNOWN(message=f"[ERROR] query_usage_http {e}")
210210

211211
def get_billing_account(self) -> dict:
212212
billing_account_name = self.billing_account_id

src/cloudforet/cost_analysis/manager/cost_manager.py

+31-4
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ def get_data(
157157
collect_scope: str = task_options["collect_scope"]
158158
tenant_ids: list = self._get_tenant_ids(task_options, collect_scope)
159159
start: datetime = self._get_first_date_of_month(task_options["start"])
160-
end: datetime = datetime.utcnow()
160+
end = self._get_end_date_from_task_options(task_options)
161161

162162
monthly_time_period = self._make_monthly_time_period(start, end)
163163
for time_period in monthly_time_period:
@@ -454,6 +454,20 @@ def _get_additional_info(self, result: dict, options: dict, tenant_id: str = Non
454454
if result.get("term") != "" and result.get("term"):
455455
additional_info["Term"] = result["term"]
456456

457+
if options.get("cost_metric") == "AmortizedCost":
458+
if result.get("pricingmodel") in ["Reservation", "SavingsPlan"]:
459+
meter_id = result.get("meterid")
460+
product_id = result.get("productid")
461+
if not self.retail_price_map.get(f"{meter_id}:{product_id}"):
462+
unit_price = self._get_unit_price_from_meter_id(
463+
meter_id, product_id
464+
)
465+
self.retail_price_map[f"{meter_id}:{product_id}"] = unit_price
466+
467+
additional_info["PayG Unit Price"] = self.retail_price_map[
468+
f"{meter_id}:{product_id}"
469+
]
470+
457471
return additional_info
458472

459473
def _get_cost_from_result_with_options(self, result: dict, options: dict) -> float:
@@ -498,9 +512,12 @@ def _get_aggregate_data(self, result: dict, options: dict) -> dict:
498512
aggregate_data["Actual Cost"] = cost_in_billing_currency
499513

500514
if result.get("pricingmodel") in ["Reservation", "SavingsPlan"]:
501-
aggregate_data["Saved Cost"] = self._get_saved_cost(
502-
result, cost_in_billing_currency
503-
)
515+
if cost_in_billing_currency > 0:
516+
aggregate_data["Saved Cost"] = self._get_saved_cost(
517+
result, cost_in_billing_currency
518+
)
519+
else:
520+
aggregate_data["Saved Cost"] = 0.0
504521

505522
else:
506523
aggregate_data["Actual Cost"] = cost_in_billing_currency
@@ -578,6 +595,8 @@ def _get_tenant_ids(task_options: dict, collect_scope: str) -> list:
578595
tenant_ids.append(task_options["tenant_id"])
579596
elif collect_scope == "customer_tenant_id":
580597
tenant_ids.extend(task_options["customer_tenants"])
598+
elif "billing_tenant_id" in task_options:
599+
tenant_ids.append(task_options["billing_tenant_id"])
581600
else:
582601
tenant_ids.append("EA Agreement")
583602
return tenant_ids
@@ -780,3 +799,11 @@ def _set_network_traffic_cost(
780799
def _combine_rows_and_columns_from_results(rows: list, columns: list):
781800
_columns = [column.get("name") for column in columns]
782801
return pd.DataFrame(data=rows, columns=_columns).to_dict(orient="records")
802+
803+
def _get_end_date_from_task_options(self, task_options: dict) -> datetime:
804+
end_date = datetime.utcnow()
805+
806+
if "end" in task_options:
807+
if end_date.strftime("%Y-%m") < task_options["end"]:
808+
end_date = self._get_last_date_of_month(end_date.year, end_date.month)
809+
return end_date

src/cloudforet/cost_analysis/manager/job_manager.py

+81-46
Original file line numberDiff line numberDiff line change
@@ -43,61 +43,96 @@ def get_tasks(
4343
changed = []
4444
synced_accounts = []
4545

46-
# divide customer tenants for each task
47-
customer_tenants, first_sync_tenants = self._get_customer_tenants(
48-
secret_data, linked_accounts
49-
)
50-
51-
if len(customer_tenants) == 0 and len(first_sync_tenants) > 0:
52-
customer_tenants.extend(first_sync_tenants)
53-
first_sync_tenants = []
46+
# Only for MicrosoftPartnerAgreement
47+
if options.get("collect_scope") == "billing_account_id":
48+
start = datetime.strptime(start_month, "%Y-%m")
49+
end = datetime.utcnow()
5450

55-
divided_customer_tenants = self._get_divided_customer_tenants(
56-
customer_tenants
57-
)
51+
month_range = relativedelta(end, start).months
52+
month_range_step = math.ceil((month_range + 1) / _TASK_LIST_SIZE)
5853

59-
for divided_customer_tenant_info in divided_customer_tenants:
60-
tasks.append(
61-
{
62-
"task_options": {
63-
"start": start_month,
64-
"account_agreement_type": billing_account_agreement_type,
65-
"collect_scope": "customer_tenant_id",
66-
"customer_tenants": divided_customer_tenant_info,
67-
"billing_tenant_id": secret_data["tenant_id"],
68-
}
69-
}
70-
)
71-
if linked_accounts:
72-
synced_accounts = self._extend_synced_accounts(
73-
synced_accounts, divided_customer_tenant_info
54+
for month in range(
55+
0,
56+
month_range + 1,
57+
math.ceil((month_range + 1) / _TASK_LIST_SIZE),
58+
):
59+
task_start_month = datetime.strftime(
60+
start + relativedelta(months=month), "%Y-%m"
61+
)
62+
task_end_month = datetime.strftime(
63+
start + relativedelta(months=month + month_range_step - 1),
64+
"%Y-%m",
7465
)
75-
changed.append({"start": start_month})
76-
if first_sync_tenants:
77-
first_sync_start_month = self._get_start_month(start=None)
78-
tasks.append(
79-
{
80-
"task_options": {
81-
"start": first_sync_start_month,
82-
"account_agreement_type": billing_account_agreement_type,
83-
"collect_scope": "customer_tenant_id",
84-
"customer_tenants": first_sync_tenants,
85-
"billing_tenant_id": secret_data["tenant_id"],
86-
"is_sync": False,
66+
tasks.append(
67+
{
68+
"task_options": {
69+
"start": task_start_month,
70+
"end": task_end_month,
71+
"account_agreement_type": billing_account_agreement_type,
72+
"collect_scope": "billing_account_id",
73+
"billing_tenant_id": secret_data["tenant_id"],
74+
}
8775
}
88-
}
76+
)
77+
if linked_accounts:
78+
synced_accounts = linked_accounts
79+
changed.append({"start": start_month})
80+
else:
81+
# divide customer tenants for each task
82+
customer_tenants, first_sync_tenants = self._get_customer_tenants(
83+
secret_data, linked_accounts
84+
)
85+
86+
if len(customer_tenants) == 0 and len(first_sync_tenants) > 0:
87+
customer_tenants.extend(first_sync_tenants)
88+
first_sync_tenants = []
89+
90+
divided_customer_tenants = self._get_divided_customer_tenants(
91+
customer_tenants
8992
)
90-
for tenant_id in first_sync_tenants:
91-
changed.append(
93+
94+
for divided_customer_tenant_info in divided_customer_tenants:
95+
tasks.append(
9296
{
93-
"start": first_sync_start_month,
94-
"filter": {"additional_info.Tenant Id": tenant_id},
97+
"task_options": {
98+
"start": start_month,
99+
"account_agreement_type": billing_account_agreement_type,
100+
"collect_scope": "customer_tenant_id",
101+
"customer_tenants": divided_customer_tenant_info,
102+
"billing_tenant_id": secret_data["tenant_id"],
103+
}
95104
}
96105
)
97-
if linked_accounts:
98-
synced_accounts = self._extend_synced_accounts(
99-
synced_accounts, first_sync_tenants
106+
if linked_accounts:
107+
synced_accounts = self._extend_synced_accounts(
108+
synced_accounts, divided_customer_tenant_info
109+
)
110+
changed.append({"start": start_month})
111+
if first_sync_tenants:
112+
first_sync_start_month = self._get_start_month(start=None)
113+
tasks.append(
114+
{
115+
"task_options": {
116+
"start": first_sync_start_month,
117+
"account_agreement_type": billing_account_agreement_type,
118+
"collect_scope": "customer_tenant_id",
119+
"customer_tenants": first_sync_tenants,
120+
"billing_tenant_id": secret_data["tenant_id"],
121+
"is_sync": False,
122+
}
123+
}
100124
)
125+
for tenant_id in first_sync_tenants:
126+
changed.append(
127+
{
128+
"start": first_sync_start_month,
129+
"filter": {"additional_info.Tenant Id": tenant_id},
130+
}
131+
)
132+
if linked_accounts:
133+
synced_accounts = self._extend_synced_accounts(
134+
synced_accounts, first_sync_tenants
135+
)
101136
else:
102137
tasks = [
103138
{

0 commit comments

Comments
 (0)