Skip to content

Commit d399ac5

Browse files
committed
feat: modify change cost data parameter (#199(
1 parent b316f13 commit d399ac5

File tree

4 files changed

+85
-103
lines changed

4 files changed

+85
-103
lines changed

src/spaceone/cost_analysis/manager/cost_manager.py

+35-16
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,17 @@ def _rollback(vo: Cost):
5050
params["billed_year"] = billed_at.strftime("%Y")
5151
params["billed_month"] = billed_at.strftime("%Y-%m")
5252

53-
params, ds_account_vo = self.data_source_account_mgr.connect_cost_data(params)
53+
(
54+
workspace_id,
55+
v_workspace_id,
56+
) = self.data_source_account_mgr.get_workspace_id_from_account_id(
57+
params["domain_id"], params["data_source_id"]
58+
)
59+
60+
if v_workspace_id:
61+
params["workspace_id"] = v_workspace_id
5462

55-
params = self.data_source_rule_mgr.change_cost_data(params, ds_account_vo)
63+
params = self.data_source_rule_mgr.change_cost_data(params, workspace_id)
5664

5765
cost_vo: Cost = self.cost_model.create(params)
5866

@@ -110,14 +118,14 @@ def get_cost(
110118
def filter_costs(self, **conditions):
111119
return self.cost_model.filter(**conditions)
112120

113-
def list_costs(self, query: dict, domain_id: str):
121+
def list_costs(self, query: dict, domain_id: str, data_source_id: str):
114122
query = self._change_filter_project_group_id(query, domain_id)
115-
# query = self._change_filter_v_workspace_id(query, domain_id)
123+
# query = self._change_filter_v_workspace_id(query, domain_id, data_source_id)
116124
return self.cost_model.query(**query)
117125

118-
def stat_costs(self, query: dict, domain_id: str):
126+
def stat_costs(self, query: dict, domain_id: str, data_source_id: str):
119127
query = self._change_filter_project_group_id(query, domain_id)
120-
# query = self._change_filter_v_workspace_id(query, domain_id)
128+
# query = self._change_filter_v_workspace_id(query, domain_id, data_source_id)
121129

122130
return self.cost_model.stat(**query)
123131

@@ -205,14 +213,14 @@ def analyze_costs_by_granularity(
205213
granularity = query["granularity"]
206214

207215
# Change filter v_workspace_id to workspace_id
208-
data_source_vo = self.data_source_mgr.get_data_source(data_source_id, domain_id)
209-
plugin_metadata = data_source_vo.plugin_info.metadata
210-
use_account_routing = plugin_metadata.get("use_account_routing", False)
211-
if use_account_routing:
212-
_LOGGER.debug(
213-
f"[analyze_costs_by_granularity] add v_workspace_id filter: {data_source_id}"
214-
)
215-
query = self._change_filter_v_workspace_id(query, domain_id)
216+
# data_source_vo = self.data_source_mgr.get_data_source(data_source_id, domain_id)
217+
# plugin_metadata = data_source_vo.plugin_info.metadata
218+
# use_account_routing = plugin_metadata.get("use_account_routing", False)
219+
# if use_account_routing:
220+
# _LOGGER.debug(
221+
# f"[analyze_costs_by_granularity] add v_workspace_id filter: {data_source_id}"
222+
# )
223+
query = self._change_filter_v_workspace_id(query, domain_id, data_source_id)
216224

217225
# Save query history to speed up data loading
218226
query_hash: str = utils.dict_to_hash(query)
@@ -446,10 +454,21 @@ def _change_filter_project_group_id(self, query: dict, domain_id: str) -> dict:
446454
query["filter"] = change_filter
447455
return query
448456

449-
def _change_filter_v_workspace_id(self, query: dict, domain_id: str) -> dict:
457+
def _change_filter_v_workspace_id(
458+
self, query: dict, domain_id: str, data_source_id: str
459+
) -> dict:
450460
change_filter = []
451461
workspace_ids = []
452-
data_source_id = self._get_data_source_id_from_filter(query)
462+
463+
data_source_vo = self.data_source_mgr.get_data_source(data_source_id, domain_id)
464+
plugin_metadata = data_source_vo.plugin_info.metadata
465+
use_account_routing = plugin_metadata.get("use_account_routing", False)
466+
if not use_account_routing:
467+
return query
468+
469+
_LOGGER.debug(
470+
f"[analyze_costs_by_granularity] add v_workspace_id filter: {data_source_id}"
471+
)
453472

454473
for condition in query.get("filter", []):
455474
key = condition.get("k", condition.get("key"))

src/spaceone/cost_analysis/manager/data_source_account_manager.py

+39-69
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
from mongoengine import QuerySet
55
from spaceone.core.manager import BaseManager
6-
from spaceone.core import utils
76

87
from spaceone.cost_analysis.model import DataSource
98
from spaceone.cost_analysis.model.data_source_account.database import DataSourceAccount
@@ -83,45 +82,28 @@ def filter_data_source_accounts(self, **conditions) -> QuerySet:
8382
def stat_data_source_accounts(self, query: dict) -> dict:
8483
return self.data_source_account_model.stat(**query)
8584

86-
def connect_cost_data(
87-
self, cost_data: dict
88-
) -> Tuple[dict, Union[DataSourceAccount, None]]:
89-
data_source_id = cost_data["data_source_id"]
90-
domain_id = cost_data["domain_id"]
85+
def get_workspace_id_from_account_id(
86+
self, domain_id: str, data_source_id: str
87+
) -> Tuple[str, str]:
88+
workspace_id = None
89+
v_workspace_id = None
9190

9291
data_source_vo = self._get_data_source(data_source_id, domain_id)
9392
plugin_info_metadata = data_source_vo.plugin_info.metadata
9493

9594
use_account_routing = plugin_info_metadata.get("use_account_routing", False)
9695

97-
ds_account_vo = None
9896
if use_account_routing:
99-
account_connect_polices: list = plugin_info_metadata.get(
100-
"account_connect_polices"
101-
)
102-
for account_connect_policy in account_connect_polices:
103-
if account_connect_policy.get("name") == "connect_cost_to_account":
104-
name = account_connect_policy.get("name")
105-
policy = account_connect_policy["polices"].get(name)
106-
source = policy["source"]
107-
target_key = policy.get("target", "account_id")
108-
target_value = utils.get_dict_value(cost_data, source)
109-
operator = policy.get("operator")
110-
111-
if target_value:
112-
ds_account_vo = self._get_data_source_account_vo(
113-
target_key,
114-
target_value,
115-
data_source_id,
116-
domain_id,
117-
operator,
118-
)
119-
120-
if ds_account_vo:
121-
cost_data["account_id"] = ds_account_vo.account_id
122-
cost_data["workspace_id"] = ds_account_vo.v_workspace_id
123-
124-
return cost_data, ds_account_vo
97+
account_match_key_value = plugin_info_metadata.get("account_match_key")
98+
if account_match_key_value:
99+
ds_account_vo = self.get_data_source_account(
100+
data_source_id, account_match_key_value, domain_id
101+
)
102+
103+
workspace_id = ds_account_vo.workspace_id
104+
v_workspace_id = ds_account_vo.v_workspace_id
105+
106+
return workspace_id, v_workspace_id
125107

126108
def connect_account_by_data_source_vo(
127109
self,
@@ -130,64 +112,52 @@ def connect_account_by_data_source_vo(
130112
) -> DataSourceAccount:
131113
domain_id = data_source_vo.domain_id
132114

133-
plugin_info_metadata = data_source_vo.plugin_info.metadata
134-
account_connect_polices: list = plugin_info_metadata.get(
135-
"account_connect_polices"
136-
)
137-
138-
for account_connect_policy in account_connect_polices:
139-
if account_connect_policy.get("name") == "connect_account_to_workspace":
140-
name = account_connect_policy.get("name")
141-
policy = account_connect_policy["polices"].get(name)
142-
source = policy["source"]
143-
target_key = policy.get("target", "references")
115+
reference_id = data_source_account_vo.account_id
116+
workspace_info = self._get_workspace_by_references(reference_id, domain_id)
117+
if workspace_info:
118+
data_source_account_vo = self.update_data_source_account_by_vo(
119+
{"workspace_id": workspace_info.get("workspace_id")},
120+
data_source_account_vo,
121+
)
144122

145-
target_value = utils.get_dict_value(
146-
data_source_account_vo.to_dict(),
147-
source,
148-
)
149-
operator = policy.get("operator")
150-
151-
if target_value:
152-
workspace_info = self._get_workspace(
153-
target_key, target_value, domain_id, operator
154-
)
155-
156-
if workspace_info:
157-
data_source_account_vo = self.update_data_source_account_by_vo(
158-
{"workspace_id": workspace_info.get("workspace_id")},
159-
data_source_account_vo,
160-
)
161123
return data_source_account_vo
162124

163-
def _get_workspace(
164-
self, target_key: str, target_value: str, domain_id: str, operator: str = "eq"
125+
def _get_workspace_by_references(
126+
self, reference_id: str, domain_id: str
165127
) -> Union[dict, None]:
166-
if f"workspace:{domain_id}:{target_key}:{target_value}" in self._workspace_info:
128+
if f"workspace:{domain_id}:references:{reference_id}" in self._workspace_info:
167129
return self._workspace_info[
168-
f"workspace:{domain_id}:{target_key}:{target_value}"
130+
f"workspace:{domain_id}:references:{reference_id}"
169131
]
170132

171133
query = {
172134
"filter": [
173135
{"k": "domain_id", "v": domain_id, "o": "eq"},
136+
{"k": "references", "v": [reference_id], "o": "in"},
174137
]
175138
}
176-
if operator == "in" and not isinstance(target_value, list):
177-
target_value = [target_value]
178-
query["filter"].append({"k": target_key, "v": target_value, "o": operator})
179139

180140
identity_mgr = self.locator.get_manager("IdentityManager")
181141
response = identity_mgr.list_workspaces({"query": query}, domain_id)
182142
results = response.get("results", [])
183143
total_count = response.get("total_count", 0)
184144

185145
workspace_info = None
186-
if total_count > 0:
146+
147+
if total_count == 0:
148+
response = identity_mgr.list_workspaces(
149+
{"query": {"filter": [{"k": "domain_id", "v": domain_id, "o": "eq"}]}},
150+
domain_id,
151+
)
152+
total_count = response.get("total_count", 0)
153+
if total_count == 1:
154+
workspace_info = response.get("results")[0]
155+
156+
else:
187157
workspace_info = results[0]
188158

189159
self._workspace_info[
190-
f"workspace:{domain_id}:{target_key}:{target_value}"
160+
f"workspace:{domain_id}:references:{reference_id}"
191161
] = workspace_info
192162

193163
return workspace_info

src/spaceone/cost_analysis/manager/data_source_rule_manager.py

+9-17
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from spaceone.core import utils
66
from spaceone.core.manager import BaseManager
77
from spaceone.cost_analysis.manager.identity_manager import IdentityManager
8-
from spaceone.cost_analysis.model import DataSourceAccount
98
from spaceone.cost_analysis.model.data_source_rule_model import (
109
DataSourceRule,
1110
DataSourceRuleCondition,
@@ -88,9 +87,7 @@ def list_data_source_rules(self, query: dict):
8887
def stat_data_source_rules(self, query):
8988
return self.data_source_rule_model.stat(**query)
9089

91-
def change_cost_data(
92-
self, cost_data: dict, data_source_account_vo: DataSourceAccount = None
93-
) -> dict:
90+
def change_cost_data(self, cost_data: dict, workspace_id: str = None) -> dict:
9491
data_source_id = cost_data["data_source_id"]
9592
domain_id = cost_data["domain_id"]
9693
(
@@ -99,11 +96,11 @@ def change_cost_data(
9996
) = self._get_data_source_rules(data_source_id, domain_id)
10097

10198
cost_data = self._apply_data_source_rule_to_cost_data(
102-
cost_data, managed_data_source_rule_vos, domain_id, data_source_account_vo
99+
cost_data, managed_data_source_rule_vos, domain_id, workspace_id
103100
)
104101

105102
cost_data = self._apply_data_source_rule_to_cost_data(
106-
cost_data, custom_data_source_rule_vos, domain_id, data_source_account_vo
103+
cost_data, custom_data_source_rule_vos, domain_id, workspace_id
107104
)
108105

109106
return cost_data
@@ -113,7 +110,7 @@ def _apply_data_source_rule_to_cost_data(
113110
cost_data: dict,
114111
data_source_rule_vos: QuerySet,
115112
domain_id: str,
116-
data_source_account_vo: DataSourceAccount = None,
113+
workspace_id: str = None,
117114
):
118115
for data_source_rule_vo in data_source_rule_vos:
119116
is_match = self._change_cost_data_by_rule(cost_data, data_source_rule_vo)
@@ -122,7 +119,7 @@ def _apply_data_source_rule_to_cost_data(
122119
cost_data,
123120
data_source_rule_vo.actions,
124121
domain_id,
125-
data_source_account_vo,
122+
workspace_id,
126123
)
127124

128125
if is_match and data_source_rule_vo.options.stop_processing:
@@ -135,13 +132,8 @@ def _change_cost_data_with_actions(
135132
cost_data: dict,
136133
actions: dict,
137134
domain_id: str,
138-
data_source_account_vo: DataSourceAccount = None,
135+
workspace_id: str = None,
139136
):
140-
if data_source_account_vo:
141-
workspace_id = data_source_account_vo.workspace_id
142-
else:
143-
workspace_id = None
144-
145137
for action, value in actions.items():
146138
if action == "change_project" and value:
147139
cost_data["project_id"] = value
@@ -156,8 +148,8 @@ def _change_cost_data_with_actions(
156148
)
157149
if project_info:
158150
cost_data["project_id"] = project_info["project_id"]
159-
if not data_source_account_vo:
160-
cost_data["workspace_id"] = project_info.get("workspace_id")
151+
if not workspace_id:
152+
cost_data["workspace_id"] = project_info["workspace_id"]
161153

162154
elif action == "match_service_account" and value:
163155
source = value["source"]
@@ -172,7 +164,7 @@ def _change_cost_data_with_actions(
172164
"service_account_id"
173165
]
174166
cost_data["project_id"] = service_account_info.get("project_id")
175-
if not data_source_account_vo:
167+
if not workspace_id:
176168
cost_data["workspace_id"] = service_account_info.get(
177169
"workspace_id"
178170
)

src/spaceone/cost_analysis/service/cost_service.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ def list(self, params):
173173

174174
query = params.get("query", {})
175175
domain_id = params["domain_id"]
176-
return self.cost_mgr.list_costs(query, domain_id)
176+
data_source_id = params["data_source_id"]
177+
return self.cost_mgr.list_costs(query, domain_id, data_source_id)
177178

178179
@transaction(
179180
permission="cost-analysis:Cost.read",

0 commit comments

Comments
 (0)