Skip to content

Commit

Permalink
Merge pull request #242 from ImMin5/master
Browse files Browse the repository at this point in the history
Add new feature 'update_permissions' for DataSource
  • Loading branch information
ImMin5 authored Jun 20, 2024
2 parents eaea907 + 64e0ff4 commit 06c32fe
Show file tree
Hide file tree
Showing 19 changed files with 324 additions and 50 deletions.
35 changes: 16 additions & 19 deletions src/spaceone/cost_analysis/interface/grpc/cost.py
Original file line number Diff line number Diff line change
@@ -1,49 +1,46 @@
from spaceone.api.cost_analysis.v1 import cost_pb2, cost_pb2_grpc
from spaceone.core.pygrpc import BaseAPI

from spaceone.cost_analysis.service import CostService

class Cost(BaseAPI, cost_pb2_grpc.CostServicer):

class Cost(BaseAPI, cost_pb2_grpc.CostServicer):
pb2 = cost_pb2
pb2_grpc = cost_pb2_grpc

def create(self, request, context):
params, metadata = self.parse_request(request, context)

with self.locator.get_service('CostService', metadata) as cost_service:
return self.locator.get_info('CostInfo', cost_service.create(params))
with self.locator.get_service("CostService", metadata) as cost_service:
return self.locator.get_info("CostInfo", cost_service.create(params))

def delete(self, request, context):
params, metadata = self.parse_request(request, context)

with self.locator.get_service('CostService', metadata) as cost_service:
with self.locator.get_service("CostService", metadata) as cost_service:
cost_service.delete(params)
return self.locator.get_info('EmptyInfo')
return self.locator.get_info("EmptyInfo")

def get(self, request, context):
params, metadata = self.parse_request(request, context)

with self.locator.get_service('CostService', metadata) as cost_service:
return self.locator.get_info('CostInfo', cost_service.get(params))
cost_svc = CostService(metadata)
response: dict = cost_svc.get(params)
return self.dict_to_message(response)

def list(self, request, context):
params, metadata = self.parse_request(request, context)

with self.locator.get_service('CostService', metadata) as cost_service:
cost_vos, total_count = cost_service.list(params)
return self.locator.get_info('CostsInfo',
cost_vos,
total_count,
minimal=self.get_minimal(params))
cost_svc = CostService(metadata)
response: dict = cost_svc.list(params)
return self.dict_to_message(response)

def analyze(self, request, context):
params, metadata = self.parse_request(request, context)

with self.locator.get_service('CostService', metadata) as cost_service:
return self.locator.get_info('StatisticsInfo', cost_service.analyze(params))
with self.locator.get_service("CostService", metadata) as cost_service:
return self.locator.get_info("StatisticsInfo", cost_service.analyze(params))

def stat(self, request, context):
params, metadata = self.parse_request(request, context)

with self.locator.get_service('CostService', metadata) as cost_service:
return self.locator.get_info('StatisticsInfo', cost_service.stat(params))
with self.locator.get_service("CostService", metadata) as cost_service:
return self.locator.get_info("StatisticsInfo", cost_service.stat(params))
8 changes: 8 additions & 0 deletions src/spaceone/cost_analysis/interface/grpc/data_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from spaceone.api.cost_analysis.v1 import data_source_pb2, data_source_pb2_grpc
from spaceone.core.pygrpc import BaseAPI

from spaceone.cost_analysis.service import DataSourceService

_LOGGER = logging.getLogger(__name__)


Expand Down Expand Up @@ -30,6 +32,12 @@ def update(self, request, context):
"DataSourceInfo", data_source_service.update(params)
)

def update_permissions(self, request, context):
params, metadata = self.parse_request(request, context)
data_source_svc = DataSourceService(metadata)
response: dict = data_source_svc.update_permissions(params)
return self.dict_to_message(response)

def update_secret_data(self, request, context):
params, metadata = self.parse_request(request, context)

Expand Down
34 changes: 25 additions & 9 deletions src/spaceone/cost_analysis/manager/cost_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ def filter_costs(self, **conditions):
return self.cost_model.filter(**conditions)

def list_costs(self, query: dict, domain_id: str, data_source_id: str):
query = self.change_filter_v_workspace_id(query, domain_id, data_source_id)
query = self._change_filter_project_group_id(query, domain_id)
return self.cost_model.query(**query)

Expand Down Expand Up @@ -204,6 +205,7 @@ def analyze_yearly_costs_with_cache(
def analyze_costs_by_granularity(
self, query: dict, domain_id: str, data_source_id: str
):
self._check_group_by(query)
self._check_date_range(query)
granularity = query["granularity"]

Expand Down Expand Up @@ -497,15 +499,6 @@ def change_filter_v_workspace_id(
query["filter"] = change_filter
return query

@staticmethod
def _get_data_source_id_from_filter(query: dict) -> str:
for condition in query.get("filter", []):
key = condition.get("k", condition.get("key"))
value = condition.get("v", condition.get("value"))

if key == "data_source_id":
return value

def _change_response_workspace_group_by(
self, response: dict, query: dict, domain_id: str, data_source_id: str
) -> dict:
Expand Down Expand Up @@ -550,3 +543,26 @@ def _get_workspace_id_from_v_workspace_id(
workspace_id = ds_account_vos[0].workspace_id

return workspace_id

@staticmethod
def _get_data_source_id_from_filter(query: dict) -> str:
for condition in query.get("filter", []):
key = condition.get("k", condition.get("key"))
value = condition.get("v", condition.get("value"))

if key == "data_source_id":
return value

@staticmethod
def _check_group_by(query: dict) -> None:
group_by = query.get("group_by", [])
for group_by_field in group_by:
if group_by_field.split(".")[0] == "data":
raise ERROR_INVALID_PARAMETER(
key=group_by_field, reason=f"Data field is not allowed to group by."
)
elif group_by_field in ["cost", "usage_quantity"]:
raise ERROR_INVALID_PARAMETER(
key=group_by_field,
reason=f"{group_by_field} are not allowed to group by.",
)
4 changes: 3 additions & 1 deletion src/spaceone/cost_analysis/manager/data_source_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ def _rollback(data_source_vo):

return data_source_vo

def update_data_source_by_vo(self, params, data_source_vo: DataSource):
def update_data_source_by_vo(
self, params, data_source_vo: DataSource
) -> DataSource:
def _rollback(old_data):
_LOGGER.info(
f"[update_data_source_by_vo._rollback] Revert Data : "
Expand Down
Empty file.
34 changes: 34 additions & 0 deletions src/spaceone/cost_analysis/model/cost/response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from typing import Union, List
from pydantic import BaseModel

__all__ = ["CostResponse", "CostsResponse"]


class CostResponse(BaseModel):
cost_id: Union[str, None] = None
cost: Union[float, None] = None
usage_quantity: Union[float, None] = None
usage_unit: Union[str, None] = None
provider: Union[str, None] = None
region_code: Union[str, None] = None
region_key: Union[str, None] = None
product: Union[str, None] = None
usage_type: Union[str, None] = None
resource: Union[str, None] = None
tags: Union[dict, None] = None
additional_info: Union[dict, None] = None
data: Union[dict, None] = None
account_id: Union[str, None] = None
service_account_id: Union[str, None] = None
project_id: Union[str, None] = None
data_source_id: Union[str, None] = None
workspace_id: Union[str, None] = None
domain_id: Union[str, None] = None
billed_year: Union[str, None] = None
billed_month: Union[str, None] = None
billed_date: Union[str, None] = None


class CostsResponse(BaseModel):
results: List[CostResponse]
total_count: int
9 changes: 2 additions & 7 deletions src/spaceone/cost_analysis/model/cost_report/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
class CostReport(MongoModel):
cost_report_id = StringField(max_length=40, generate_id="cost-report", unique=True)
cost = DictField(default={})
status = StringField(
max_length=20, choices=("IN_PROGRESS", "SUCCESS"), default="IN_PROGRESS"
)
status = StringField(max_length=20, choices=("IN_PROGRESS", "SUCCESS"))
report_number = StringField(max_length=255)
currency = StringField(choices=["KRW", "USD", "JPY"], default="KRW")
currency_date = StringField(max_length=20)
Expand Down Expand Up @@ -39,8 +37,5 @@ class CostReport(MongoModel):
"-created_at",
"-report_number",
],
"indexes": [
"cost_report_config_id",
"domain_id",
],
"indexes": ["cost_report_config_id", "status", "domain_id", "workspace_id"],
}
1 change: 1 addition & 0 deletions src/spaceone/cost_analysis/model/cost_report/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class CostReportGetRequest(BaseModel):
class CostReportSearchQueryRequest(BaseModel):
query: Union[dict, None] = None
cost_report_id: Union[str, None] = None
cost_report_config_id: Union[str, None] = None
status: Union[Status, None] = None
issue_date: Union[str, None] = None
workspace_name: Union[str, None] = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,7 @@ class CostReportConfig(MongoModel):
"created_at",
],
"ordering": ["-created_at"],
"indexes": [
"state",
"domain_id",
"cost_report_config_id",
],
"indexes": ["state", "domain_id"],
}

@queryset_manager
Expand Down
3 changes: 0 additions & 3 deletions src/spaceone/cost_analysis/model/cost_report_data/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
"CostReportDataStatQueryRequest",
]

State = Literal["ENABLED", "DISABLED", "PENDING"]
AuthType = Literal["LOCAL", "EXTERNAL"]


class CostReportDataSearchQueryRequest(BaseModel):
query: Union[dict, None] = None
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from datetime import datetime
from typing import Union, List
from pydantic import BaseModel

from spaceone.core import utils

__all__ = ["CostReportDataResponse", "CostReportsDataResponse"]
Expand Down
Empty file.
Empty file.
16 changes: 16 additions & 0 deletions src/spaceone/cost_analysis/model/data_source/request.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from typing import Union, Literal
from pydantic import BaseModel

__all__ = [
"DataSourceUpdatePermissionsRequest",
]
State = Literal["ENABLED", "DISABLED"]
DataSourceType = Literal["LOCAL", "EXTERNAL"]
SecretType = Literal["MANUAL", "USE_SERVICE_ACCOUNT_SECRET"]
ResourceGroup = Literal["DOMAIN", "WORKSPACE"]


class DataSourceUpdatePermissionsRequest(BaseModel):
data_source_id: str
permissions: dict
domain_id: str
50 changes: 50 additions & 0 deletions src/spaceone/cost_analysis/model/data_source/response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from datetime import datetime
from typing import Union, Literal
from pydantic import BaseModel

from spaceone.core import utils

from spaceone.cost_analysis.model.data_source.request import (
State,
DataSourceType,
SecretType,
ResourceGroup,
)

__all__ = [
"DataSourceResponse",
]


class DataSourceResponse(BaseModel):
data_source_id: Union[str, None] = None
name: Union[str, None] = None
state: Union[State, None] = None
data_source_type: Union[DataSourceType, None] = None
permissions: Union[dict, None] = None
provider: Union[str, None] = None
secret_type: Union[SecretType, None] = None
secret_filter: Union[dict, None] = None
plugin_info: Union[dict, None] = None
template: Union[dict, None] = None
tags: Union[dict, None] = None
cost_tag_keys: Union[list, None] = None
cost_additional_info_keys: Union[list, None] = None
cost_data_keys: Union[list, None] = None
data_source_account_count: Union[int, None] = None
connected_workspace_count: Union[int, None] = None
resource_group: Union[ResourceGroup, None] = None
workspace_id: Union[str, None] = None
domain_id: Union[str, None] = None
created_at: Union[datetime, None] = None
updated_at: Union[datetime, None] = None
last_synchronized_at: Union[datetime, None] = None

def dict(self, *args, **kwargs):
data = super().dict(*args, **kwargs)
data["created_at"] = utils.datetime_to_iso8601(data["created_at"])
data["updated_at"] = utils.datetime_to_iso8601(data.get("updated_at"))
data["last_synchronized_at"] = utils.datetime_to_iso8601(
data.get("last_synchronized_at")
)
return data
4 changes: 4 additions & 0 deletions src/spaceone/cost_analysis/model/data_source_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class DataSource(MongoModel):
choices=("MANUAL", "USE_SERVICE_ACCOUNT_SECRET"),
)
secret_filter = EmbeddedDocumentField(SecretFilter, default=None, null=True)
permissions = DictField(default=None, null=True)
provider = StringField(max_length=40, default=None, null=True)
plugin_info = EmbeddedDocumentField(PluginInfo, default=None, null=True)
template = DictField(default={})
Expand All @@ -58,16 +59,19 @@ class DataSource(MongoModel):
workspace_id = StringField(max_length=40)
domain_id = StringField(max_length=40)
created_at = DateTimeField(auto_now_add=True)
updated_at = DateTimeField(auto_now=True)
last_synchronized_at = DateTimeField(default=None, null=True)

meta = {
"updatable_fields": [
"name",
"state",
"permissions",
"plugin_info",
"secret_filter",
"template",
"tags",
"updated_at",
"last_synchronized_at",
"cost_tag_keys",
"cost_additional_info_keys",
Expand Down
14 changes: 12 additions & 2 deletions src/spaceone/cost_analysis/service/cost_report_serivce.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,11 @@ def get(self, params: CostReportGetRequest) -> Union[CostReportResponse, dict]:
)
@append_query_filter(
[
"cost_report_id",
"cost_report_config_id",
"status",
"workspace_id",
"domain_id",
"workspace_id",
"cost_report_id",
]
)
@append_keyword_filter(
Expand Down Expand Up @@ -174,6 +175,15 @@ def list(
]
return CostReportsResponse(results=cost_reports_info, total_count=total_count)

@transaction(
permission="cost-analysis:CostReport.read",
role_types=["DOMAIN_ADMIN", "WORKSPACE_OWNER"],
)
@append_query_filter(["cost_config_report_id", "domain_id"])
@convert_model
def analyze(self):
pass

@transaction(
permission="cost-analysis:CostReport.read",
role_types=["DOMAIN_ADMIN", "WORKSPACE_OWNER"],
Expand Down
Loading

0 comments on commit 06c32fe

Please sign in to comment.