Skip to content

Commit 4b1ebf9

Browse files
authored
Merge pull request #79 from ImMin5/feature-modify-cost-option
Add feature for multiple data_source secrets
2 parents eb5c7f4 + 36b5b45 commit 4b1ebf9

File tree

3 files changed

+117
-63
lines changed

3 files changed

+117
-63
lines changed

src/cloudforet/cost_analysis/main.py

+57-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ def data_source_init(params: dict) -> dict:
2222
}
2323
"""
2424
data_source_mgr = DataSourceManager()
25-
print(params)
2625
return data_source_mgr.init_response(**params)
2726

2827

@@ -67,9 +66,27 @@ def job_get_tasks(params: dict) -> dict:
6766
}
6867
6968
"""
69+
tasks = {
70+
"tasks": [],
71+
"changed": [],
72+
"synced_accounts": [],
73+
}
74+
7075
job_mgr = JobManager()
7176
params["schema"] = params.pop("schema_name", None)
72-
return job_mgr.get_tasks(**params)
77+
secret_data = params.pop("secret_data")
78+
79+
secrets = secret_data.get("secrets", [secret_data])
80+
for _secret_data in secrets:
81+
params["secret_data"] = _secret_data
82+
job_tasks = job_mgr.get_tasks(**params)
83+
84+
tasks["tasks"].extend(job_tasks.get("tasks", []))
85+
tasks["changed"].extend(job_tasks.get("changed", []))
86+
tasks["synced_accounts"].extend(job_tasks.get("synced_accounts", []))
87+
88+
tasks["changed"] = __remove_duplicate_list_of_dict(tasks.get("changed", []))
89+
return tasks
7390

7491

7592
@app.route("Cost.get_linked_accounts")
@@ -89,9 +106,17 @@ def cost_get_linked_accounts(params: dict) -> dict:
89106
'results': 'list'
90107
}
91108
"""
109+
result = []
92110
cost_mgr = CostManager()
93111
params["schema"] = params.pop("schema_name", None)
94-
return cost_mgr.get_linked_accounts(**params)
112+
secret_data = params.pop("secret_data")
113+
114+
secrets = secret_data.get("secrets", [secret_data])
115+
for _secret_data in secrets:
116+
params["secret_data"] = _secret_data
117+
result.extend(cost_mgr.get_linked_accounts(**params))
118+
119+
return {"results": result}
95120

96121

97122
@app.route("Cost.get_data")
@@ -127,7 +152,12 @@ def cost_get_data(params: dict) -> Generator[dict, None, None]:
127152
cost_mgr = CostManager()
128153
options = params.get("options", {})
129154
task_options = params.get("task_options", {})
155+
secret_data = params.pop("secret_data")
156+
130157
params["schema"] = params.pop("schema_name", None)
158+
params["secret_data"] = __get_secret_data_with_tenant_id(
159+
secret_data, task_options.get("tenant_id")
160+
)
131161

132162
if options.get("cost_metric") == "AmortizedCost" and task_options.get(
133163
"is_benefit_job", False
@@ -137,3 +167,27 @@ def cost_get_data(params: dict) -> Generator[dict, None, None]:
137167
else:
138168
for cost_response in cost_mgr.get_data(**params):
139169
yield {"results": cost_response}
170+
171+
172+
def __remove_duplicate_list_of_dict(changed: list) -> list:
173+
seen = set()
174+
unique_list = []
175+
for changed_info in changed:
176+
# Convert dictionary to frozenset of tuples
177+
frozenset_changed_info = frozenset(changed_info.items())
178+
if frozenset_changed_info not in seen:
179+
seen.add(frozenset_changed_info)
180+
unique_list.append(changed_info)
181+
return unique_list
182+
183+
184+
def __get_secret_data_with_tenant_id(secret_data: dict, tenant_id: str = None) -> dict:
185+
secrets = secret_data.get("secrets", [secret_data])
186+
if len(secrets) == 1:
187+
return secrets[0]
188+
189+
for _secret_data in secrets:
190+
if _secret_data["tenant_id"] == tenant_id:
191+
secret_data = _secret_data
192+
193+
return secret_data

src/cloudforet/cost_analysis/manager/cost_manager.py

+57-57
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ def __init__(self, *args, **kwargs):
2626
self.retail_price_map = {}
2727

2828
def get_linked_accounts(
29-
self,
30-
options: dict,
31-
secret_data: dict,
32-
schema: str,
33-
domain_id: str,
34-
) -> dict:
29+
self,
30+
options: dict,
31+
secret_data: dict,
32+
schema: str,
33+
domain_id: str,
34+
) -> list:
3535
self.azure_cm_connector.create_session(options, secret_data, schema)
3636
billing_account_info = self.azure_cm_connector.get_billing_account()
3737
agreement_type = billing_account_info.get("agreement_type")
@@ -54,15 +54,15 @@ def get_linked_accounts(
5454
_LOGGER.debug(
5555
f"[get_linked_accounts] total accounts count: {len(accounts_info)}, domain_id: {domain_id}"
5656
)
57-
return {"results": accounts_info}
57+
return accounts_info
5858

5959
def get_benefit_data(
60-
self,
61-
options: dict,
62-
secret_data: dict,
63-
schema: str,
64-
task_options: dict,
65-
domain_id: str,
60+
self,
61+
options: dict,
62+
secret_data: dict,
63+
schema: str,
64+
task_options: dict,
65+
domain_id: str,
6666
):
6767
self.azure_cm_connector.create_session(options, secret_data, schema)
6868
start: datetime = self._get_first_date_of_month(task_options["start"])
@@ -85,12 +85,12 @@ def get_benefit_data(
8585
)
8686

8787
def _make_benefit_cost_data(
88-
self,
89-
results: dict,
90-
end: datetime,
91-
options: dict,
92-
tenant_id: str = None,
93-
agreement_type: str = None,
88+
self,
89+
results: dict,
90+
end: datetime,
91+
options: dict,
92+
tenant_id: str = None,
93+
agreement_type: str = None,
9494
) -> list:
9595
benefit_costs_data = []
9696
try:
@@ -143,12 +143,12 @@ def _make_benefit_cost_info(self, result: dict, billed_at: str) -> dict:
143143
return data
144144

145145
def get_data(
146-
self,
147-
options: dict,
148-
secret_data: dict,
149-
schema: str,
150-
task_options: dict,
151-
domain_id: str,
146+
self,
147+
options: dict,
148+
secret_data: dict,
149+
schema: str,
150+
task_options: dict,
151+
domain_id: str,
152152
) -> list:
153153
self.azure_cm_connector.create_session(options, secret_data, schema)
154154
self._check_task_options(task_options)
@@ -202,12 +202,12 @@ def get_data(
202202
yield []
203203

204204
def _make_cost_data(
205-
self,
206-
results: list,
207-
end: datetime,
208-
options: dict,
209-
tenant_id: str = None,
210-
agreement_type: str = None,
205+
self,
206+
results: list,
207+
end: datetime,
208+
options: dict,
209+
tenant_id: str = None,
210+
agreement_type: str = None,
211211
) -> list:
212212
"""Source Data Model"""
213213

@@ -248,14 +248,14 @@ def _make_transaction_cost_data(self, tenant_id: str, end: datetime) -> list:
248248

249249
try:
250250
for (
251-
reservation_transaction
251+
reservation_transaction
252252
) in self.azure_cm_connector.list_reservation_transactions_by_billing_profile_id(
253253
query_filter
254254
):
255255

256256
if (
257-
reservation_transaction.invoice_section_id.split("/")[-1]
258-
== invoice_section_id
257+
reservation_transaction.invoice_section_id.split("/")[-1]
258+
== invoice_section_id
259259
):
260260
reservation_transaction_info = (
261261
self.azure_cm_connector.convert_nested_dictionary(
@@ -312,12 +312,12 @@ def _make_transaction_cost_data(self, tenant_id: str, end: datetime) -> list:
312312
return transaction_cost_data
313313

314314
def _make_data_info(
315-
self,
316-
result: dict,
317-
billed_date: str,
318-
options: dict,
319-
tenant_id: str = None,
320-
agreement_type: str = None,
315+
self,
316+
result: dict,
317+
billed_date: str,
318+
options: dict,
319+
tenant_id: str = None,
320+
agreement_type: str = None,
321321
):
322322
additional_info: dict = self._get_additional_info(result, options, tenant_id)
323323
cost: float = self._get_cost_from_result_with_options(result, options)
@@ -391,8 +391,8 @@ def _get_additional_info(self, result: dict, options: dict, tenant_id: str = Non
391391
additional_info["Benefit Name"] = benefit_name
392392

393393
if (
394-
result.get("pricingmodel") == "Reservation"
395-
and result["metercategory"] == ""
394+
result.get("pricingmodel") == "Reservation"
395+
and result["metercategory"] == ""
396396
):
397397
result["metercategory"] = self._set_product_from_benefit_name(
398398
benefit_name
@@ -404,14 +404,14 @@ def _get_additional_info(self, result: dict, options: dict, tenant_id: str = Non
404404
if result.get("metersubcategory") != "" and result.get("metersubcategory"):
405405
additional_info["Meter SubCategory"] = result.get("metersubcategory")
406406
if (
407-
result.get("pricingmodel") == "OnDemand"
408-
and result.get("metercategory") == ""
407+
result.get("pricingmodel") == "OnDemand"
408+
and result.get("metercategory") == ""
409409
):
410410
result["metercategory"] = result.get("metercategory")
411411

412412
if result.get("customername") is None:
413413
if result.get("invoicesectionname") != "" and result.get(
414-
"invoicesectionname"
414+
"invoicesectionname"
415415
):
416416
additional_info["Department Name"] = result.get("invoicesectionname")
417417
elif result.get("departmentname") != "" and result.get("departmentname"):
@@ -420,7 +420,7 @@ def _get_additional_info(self, result: dict, options: dict, tenant_id: str = Non
420420
if result.get("accountname") != "" and result.get("accountname"):
421421
additional_info["Enrollment Account Name"] = result["accountname"]
422422
elif result.get("enrollmentaccountname") != "" and result.get(
423-
"enrollmentaccountname"
423+
"enrollmentaccountname"
424424
):
425425
additional_info["Enrollment Account Name"] = result["enrollmentaccountname"]
426426

@@ -429,9 +429,9 @@ def _get_additional_info(self, result: dict, options: dict, tenant_id: str = Non
429429

430430
collect_resource_id = options.get("collect_resource_id", False)
431431
if (
432-
collect_resource_id
433-
and result.get("resourceid") != ""
434-
and result.get("resourceid")
432+
collect_resource_id
433+
and result.get("resourceid") != ""
434+
and result.get("resourceid")
435435
):
436436
additional_info["Resource Id"] = result["resourceid"]
437437
additional_info["Resource Name"] = result["resourceid"].split("/")[-1]
@@ -569,10 +569,10 @@ def _get_tenant_ids(task_options: dict, collect_scope: str) -> list:
569569

570570
@staticmethod
571571
def _make_scope(
572-
secret_data: dict,
573-
task_options: dict,
574-
collect_scope: str,
575-
customer_tenant_id: str = None,
572+
secret_data: dict,
573+
task_options: dict,
574+
collect_scope: str,
575+
customer_tenant_id: str = None,
576576
):
577577
if collect_scope == "subscription_id":
578578
subscription_id = task_options["subscription_id"]
@@ -673,7 +673,7 @@ def _convert_date_format_to_utc(date_format: str) -> datetime:
673673
return datetime.strptime(date_format, "%Y-%m-%d").replace(tzinfo=timezone.utc)
674674

675675
def _make_monthly_time_period(
676-
self, start_date: datetime, end_date: datetime
676+
self, start_date: datetime, end_date: datetime
677677
) -> list:
678678
monthly_time_period = []
679679
current_date = end_date
@@ -703,7 +703,7 @@ def _make_monthly_time_period(
703703

704704
@staticmethod
705705
def _get_linked_customer_tenants(
706-
secret_data: dict, billing_accounts_info: list
706+
secret_data: dict, billing_accounts_info: list
707707
) -> list:
708708
customer_tenants = secret_data.get("customer_tenants", [])
709709
if not customer_tenants:
@@ -716,7 +716,7 @@ def _get_linked_customer_tenants(
716716

717717
@staticmethod
718718
def _make_accounts_info_from_customer_tenants(
719-
billing_accounts_info: list, customer_tenants: list
719+
billing_accounts_info: list, customer_tenants: list
720720
) -> list:
721721
accounts_info = []
722722
for billing_account_info in billing_accounts_info:
@@ -754,7 +754,7 @@ def _exclude_cost_data_with_options(result: dict, options: dict) -> bool:
754754

755755
@staticmethod
756756
def _set_network_traffic_cost(
757-
additional_info: dict, product: str, usage_type: str
757+
additional_info: dict, product: str, usage_type: str
758758
) -> dict:
759759
if product in ["Bandwidth", "Content Delivery Network"]:
760760
additional_info["Usage Type Details"] = usage_type

src/cloudforet/cost_analysis/manager/job_manager.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ def get_tasks(
6464
"account_agreement_type": billing_account_agreement_type,
6565
"collect_scope": "customer_tenant_id",
6666
"customer_tenants": divided_customer_tenant_info,
67+
"tenant_id": secret_data["tenant_id"],
6768
}
6869
}
6970
)
@@ -81,6 +82,7 @@ def get_tasks(
8182
"account_agreement_type": billing_account_agreement_type,
8283
"collect_scope": "customer_tenant_id",
8384
"customer_tenants": first_sync_tenants,
85+
"tenant_id": secret_data["tenant_id"],
8486
"is_sync": False,
8587
}
8688
}
@@ -104,6 +106,7 @@ def get_tasks(
104106
"start": start_month,
105107
"account_agreement_type": billing_account_agreement_type,
106108
"collect_scope": "billing_account_id",
109+
"tenant_id": secret_data["tenant_id"],
107110
"is_benefit_job": True,
108111
}
109112
}
@@ -142,9 +145,6 @@ def get_tasks(
142145
raise ERROR_INVALID_SECRET_TYPE(secret_type=options.get("secret_type"))
143146

144147
tasks = {"tasks": tasks, "changed": changed, "synced_accounts": synced_accounts}
145-
146-
print(tasks)
147-
148148
return tasks
149149

150150
def _get_tenants_from_billing_account(self):

0 commit comments

Comments
 (0)