Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
2228dca
feat: improve budget service currency handling
ImMin5 Mar 28, 2025
6fd4588
fix: fix create cost report error at caused end of month
ImMin5 Mar 31, 2025
e6e8882
feat: modify field name notifications -> notification
ImMin5 Apr 11, 2025
07ea57c
Merge pull request #334 from ImMin5/master
ImMin5 Apr 11, 2025
e01971f
feat: add budget_manager_id field for Budget
ImMin5 Apr 11, 2025
04e7288
Merge pull request #335 from ImMin5/master
ImMin5 Apr 11, 2025
b63beac
feat: implement budget utilization rate update scheduler and related …
ImMin5 Apr 14, 2025
8de2353
deploy: update chart version `1.4.1` -> '1.4.2'
ImMin5 Apr 14, 2025
dcfbea5
chore: rename budget update job name
ImMin5 Apr 14, 2025
177b933
chore: modify log message
ImMin5 Apr 14, 2025
0bb93de
Merge pull request #336 from ImMin5/master
ImMin5 Apr 14, 2025
3402536
fix: add convert model decorator at stat api
ImMin5 Apr 14, 2025
a939a16
Merge pull request #337 from ImMin5/master
ImMin5 Apr 14, 2025
4477f39
feat: add budget year field and modify budget update scheduler
ImMin5 Apr 15, 2025
c57ea93
Merge pull request #338 from ImMin5/master
ImMin5 Apr 15, 2025
e373a56
feat: implement validation logic when sa budget created
ImMin5 Apr 15, 2025
38f147d
feat: modify budget and budget usage index order
ImMin5 Apr 15, 2025
f37567b
feat: add budget manager notification field
ImMin5 Apr 15, 2025
4b8fb13
fix: fix typo
ImMin5 Apr 15, 2025
1798d79
Merge pull request #339 from ImMin5/master
ImMin5 Apr 15, 2025
032456a
refactor: migrate cost report services to UnifiedCost model
Apr 16, 2025
4f61e7f
chore: apply to openai hint
Apr 16, 2025
6b58ed0
feat: enhance budget notification logic
ImMin5 Apr 17, 2025
7107b02
feat: rename budget utilization method
ImMin5 Apr 17, 2025
e78e742
Merge pull request #341 from ImMin5/master
ImMin5 Apr 17, 2025
5035138
feat: modify cost report run scheduler class name
ImMin5 Apr 17, 2025
e69ef09
Merge pull request #342 from ImMin5/master
ImMin5 Apr 17, 2025
4d21c01
feat: update workflow to use Ubuntu 22.04
ImMin5 Apr 17, 2025
89502bf
Merge pull request #343 from ImMin5/master
ImMin5 Apr 17, 2025
0462b11
[CI] Deploy CI
admin-cloudforet Apr 17, 2025
4e5a995
feat: add `budget_manageR_id` element for budget stat keyword filter …
ImMin5 Apr 17, 2025
ddc3995
Merge pull request #344 from ImMin5/master
ImMin5 Apr 17, 2025
3eef08f
feat: add error handling for unverified budget managers and update no…
ImMin5 Apr 18, 2025
cd5aead
Merge pull request #345 from ImMin5/master
ImMin5 Apr 18, 2025
6c0ec11
feat: enhance budget management with optional workspace_id and refact…
ImMin5 Apr 18, 2025
f326f4c
feat: refactor budget plan validation
ImMin5 Apr 18, 2025
c4eee41
Merge pull request #346 from ImMin5/master
ImMin5 Apr 18, 2025
0dad90a
chore: change field names
Apr 21, 2025
9ba454c
feat: add budget state field and improve budget usage update logic
ImMin5 Apr 21, 2025
96ebfb2
Merge pull request #347 from ImMin5/master
ImMin5 Apr 21, 2025
1bfa2a3
feat: implement budget state update job scheduling and enhance budget…
ImMin5 Apr 22, 2025
cc90b4a
Merge pull request #348 from ImMin5/master
ImMin5 Apr 22, 2025
e275753
feat: add service_account_id field to budget usage model
ImMin5 Apr 22, 2025
f50dce4
Merge pull request #349 from ImMin5/master
ImMin5 Apr 22, 2025
173d18e
feat: add service_account_id field to budget usage list request query…
ImMin5 Apr 22, 2025
bef1d02
Merge pull request #350 from ImMin5/master
ImMin5 Apr 22, 2025
39b9699
Merge pull request #340 from stat-kwon/master
stat-kwon Apr 23, 2025
a471790
Revert "Migrate cost report services to UnifiedCost model"
stat-kwon Apr 23, 2025
0aaee47
Merge pull request #351 from cloudforet-io/revert-340-master
stat-kwon Apr 23, 2025
1c5caac
feat: unified cost analysis with domain_id filtering
ImMin5 Apr 23, 2025
9526f50
Merge pull request #352 from ImMin5/feature-unified-cost-pg-filter
ImMin5 Apr 23, 2025
7f619fc
feat: add error handling for duplicated budget thresholds
ImMin5 Apr 24, 2025
5d5a41d
Merge pull request #353 from ImMin5/master
ImMin5 Apr 24, 2025
25b74f2
feat: update workspace_id field to be optional when get budget info
ImMin5 Apr 24, 2025
b5b2a41
Merge pull request #354 from ImMin5/master
ImMin5 Apr 24, 2025
8f1e43d
feat: fix merge conflict
ImMin5 Apr 28, 2025
d91c18e
fix: fix schedule logic from DataSource
jinyoungmoonDEV Feb 7, 2025
ec32f24
refactor: refactoring cost_report
jinyoungmoonDEV Feb 10, 2025
d616e49
refactor: refactoring manager files
jinyoungmoonDEV Mar 4, 2025
ab10925
refactor: refactoring interface & manager files
jinyoungmoonDEV Apr 2, 2025
1782092
fix: fix update master commit from 235f5fe to 505e89d
jinyoungmoonDEV Apr 2, 2025
fd7e140
fix: fix update master commit from 6a01a04 to be1ef56
jinyoungmoonDEV Apr 2, 2025
35f5b4b
fix: fix update master commit from 266718b to f34e222
jinyoungmoonDEV Apr 3, 2025
9ae5428
fix: fix services params data handling
jinyoungmoonDEV Apr 3, 2025
eccef7e
fix: remove locator logic
jinyoungmoonDEV Apr 9, 2025
f246eb8
fix: fix import method from managers
jinyoungmoonDEV Apr 9, 2025
f7298cb
refactor: fix some useless imports
jinyoungmoonDEV Apr 9, 2025
e88cc25
fix: fix error from refactoring
jinyoungmoonDEV Apr 9, 2025
8f2eee6
fix: add @convert_model
jinyoungmoonDEV Apr 10, 2025
084c6e6
fix: fix inapposite merged code
jinyoungmoonDEV Apr 11, 2025
e4fc889
fix: fix locator logic
jinyoungmoonDEV Apr 11, 2025
89180aa
fix: fix simple import codes
jinyoungmoonDEV Apr 14, 2025
46e4171
fix: fix some models
jinyoungmoonDEV Apr 28, 2025
aaa77a1
refactor: improve code formatting and readability in multiple services
ImMin5 Apr 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/dispatch_daily_build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:

scan:
needs: docker
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- name: Run Trivy vulnerability scanner
id: trivy-scan
Expand All @@ -89,7 +89,7 @@ jobs:
echo "$count"

- name: slack
if: ${{ steps.vulnerabilities.outputs.result_count != 0 }}
if: ${{ steps.vulnerabilities.outputs.result_count != 0 }}
uses: 8398a7/action-slack@v3
with:
status: custom
Expand Down
2 changes: 1 addition & 1 deletion deploy/helm/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ description: SpaceONE Cost Analysis Helm chart for Kubernetes

type: application

version: 1.4.1
version: 1.4.2
appVersion: 1.x.y

12 changes: 12 additions & 0 deletions deploy/helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ application_scheduler:
queue: cost_analysis_q
interval: 1
minute: ':00'
cost_report_run_scheduler:
backend: spaceone.cost_analysis.interface.task.v1.cost_report_run_scheduler.CostReportRunScheduler
queue: cost_analysis_q
interval: 1
minute: ':00'
budget_update_scheduler:
backend: spaceone.cost_analysis.interface.task.v1.budget_update_scheduler.BudgetUpdateScheduler
queue: cost_analysis_q
interval: 1
minute: ':00'



# Overwrite worker config
application_worker:
Expand Down
10 changes: 4 additions & 6 deletions src/spaceone/cost_analysis/conf/global_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
}
}

# Budget Settings
BUDGET_UPDATE_DAY = 1 # Every 1st day of month
BUDGET_UPDATE_HOUR = 0

# Cost Report Config Settings
COST_REPORT_CONFIG_DEFAULT_ISSUE_DAY = 10
COST_REPORT_DEFAULT_CURRENCY = "KRW" # KRW | USD | JPY
Expand Down Expand Up @@ -98,12 +102,6 @@
UNIFIED_COST_RUN_HOUR = 0 # Hour (UTC)
UNIFIED_COST_AGGREGATION_DAY = 15 # Day

DEFAULT_EXCHANGE_RATE = {
# 'KRW': 1178.7,
# 'JPY': 114,
# 'CNY': 6.3
}

INSTALLED_DATA_SOURCE_PLUGINS = [
# {
# 'name': '',
Expand Down
1 change: 1 addition & 0 deletions src/spaceone/cost_analysis/connector/currency_connector.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import FinanceDataReader as fdr
import logging
import pandas as pd
import requests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from spaceone.core.connector import BaseConnector
from spaceone.core.auth.jwt.jwt_util import JWTUtil
from spaceone.core.connector.space_connector import SpaceConnector

__all__ = ["DataSourcePluginConnector"]

Expand All @@ -24,9 +25,7 @@ def initialize(self, endpoint):
if static_endpoint:
endpoint = static_endpoint

self.client = self.locator.get_connector(
"SpaceConnector", endpoint=endpoint, token="NO_TOKEN"
)
self.client = SpaceConnector(endpoint=endpoint, token="NO_TOKEN")

self.secret_data = self.config.get("secret_data")
self.options = self.config.get("options")
Expand Down
20 changes: 13 additions & 7 deletions src/spaceone/cost_analysis/error/budget.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,32 +30,38 @@ class ERROR_DATE_IS_WRONG(ERROR_INVALID_ARGUMENT):


class ERROR_UNIT_IS_REQUIRED(ERROR_INVALID_ARGUMENT):
_message = (
"Unit is required for notifications (key = notifications, value = {value})"
)
_message = "Unit is required for notification (key = notification, value = {value})"


class ERROR_NOTIFICATION_TYPE_IS_REQUIRED(ERROR_INVALID_ARGUMENT):
_message = "Notification type is required for notifications (key = notifications, value = {value})"
_message = "Notification type is required for notification (key = notification, value = {value})"


class ERROR_THRESHOLD_IS_WRONG(ERROR_INVALID_ARGUMENT):
_message = (
"Threshold must be greater than zero. (key = notifications, value = {value})"
"Threshold must be greater than zero. (key = notification, value = {value})"
)


class ERROR_THRESHOLD_IS_WRONG_IN_PERCENT_TYPE(ERROR_INVALID_ARGUMENT):
_message = "In percentage type, the threshold must be less than 100. (key = notifications, value = {value})"
_message = "In percentage type, the threshold must be less than 100. (key = notification, value = {value})"


class ERROR_PROVIDER_FILTER_IS_EMPTY(ERROR_INVALID_ARGUMENT):
_message = "Provider filter is empty. (key = provider_filter.providers, value = [])"


class ERROR_BUDGET_ALREADY_EXIST(ERROR_INVALID_ARGUMENT):
_message = "Budget already exist. (service_account_id = {service_account_id}, workspace_id= {workspace_id}, target = {target})"
_message = "Budget already exist. (start = {start} end = {end}, target = {target}, workspace_id = {workspace_id})"


class ERROR_NOTIFICATION_IS_NOT_SUPPORTED_IN_PROJECT(ERROR_INVALID_ARGUMENT):
_message = "Notification is not supported in project. (target = {target})"


class ERROR_BUDGET_MANAGER_IS_NOT_VERIFIED(ERROR_INVALID_ARGUMENT):
_message = "To assign as a budget manager to a user, email verification is required. (user_id = {user_id})"


class ERROR_DUPLICATED_THRESHOLD(ERROR_INVALID_ARGUMENT):
_message = "Duplicate threshold in notification. (threshold = {threshold})"
7 changes: 0 additions & 7 deletions src/spaceone/cost_analysis/info/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +0,0 @@
from spaceone.cost_analysis.info.common_info import *
from spaceone.cost_analysis.info.data_source_info import *
from spaceone.cost_analysis.info.data_source_rule_info import *
from spaceone.cost_analysis.info.cost_info import *
from spaceone.cost_analysis.info.cost_query_set_info import *
from spaceone.cost_analysis.info.job_info import *
from spaceone.cost_analysis.info.job_task_info import *
16 changes: 0 additions & 16 deletions src/spaceone/cost_analysis/info/common_info.py

This file was deleted.

49 changes: 0 additions & 49 deletions src/spaceone/cost_analysis/info/cost_info.py

This file was deleted.

39 changes: 0 additions & 39 deletions src/spaceone/cost_analysis/info/cost_query_set_info.py

This file was deleted.

92 changes: 0 additions & 92 deletions src/spaceone/cost_analysis/info/data_source_info.py
Original file line number Diff line number Diff line change
@@ -1,92 +0,0 @@
import functools
from spaceone.api.cost_analysis.v1 import data_source_pb2
from spaceone.core.pygrpc.message_type import *
from spaceone.core import utils
from spaceone.cost_analysis.model.data_source_model import DataSource

__all__ = ["DataSourceInfo", "DataSourcesInfo"]


def SecretFilterInfo(secret_filter_vo):
if secret_filter_vo:
info = {
"state": secret_filter_vo.state,
"secrets": secret_filter_vo.secrets,
"service_accounts": secret_filter_vo.service_accounts,
"schemas": secret_filter_vo.schemas,
}
return data_source_pb2.SecretFilter(**info)
else:
return None


def PluginInfo(vo):
if vo:
info = {
"plugin_id": vo.plugin_id,
"version": vo.version,
"options": change_struct_type(vo.options),
"metadata": change_struct_type(vo.metadata),
"secret_id": vo.secret_id,
"schema_id": vo.schema_id,
"upgrade_mode": vo.upgrade_mode,
}

return data_source_pb2.PluginInfo(**info)
else:
return None


def ScheduleInfo(vo):
if vo:
info = {
"state": vo.state,
"hour": vo.hour,
}

return data_source_pb2.Schedule(**info)
else:
return None


def DataSourceInfo(data_source_vo: DataSource, minimal=False):
info = {
"data_source_id": data_source_vo.data_source_id,
"workspace_id": data_source_vo.workspace_id,
"name": data_source_vo.name,
"data_source_type": data_source_vo.data_source_type,
"secret_type": data_source_vo.secret_type,
"provider": data_source_vo.provider,
"resource_group": data_source_vo.resource_group,
"schedule": ScheduleInfo(data_source_vo.schedule),
}

if not minimal:
info.update(
{
"plugin_info": PluginInfo(data_source_vo.plugin_info),
"secret_filter": SecretFilterInfo(data_source_vo.secret_filter),
"template": change_struct_type(data_source_vo.template),
"permissions": change_struct_type(data_source_vo.permissions),
"tags": change_struct_type(data_source_vo.tags),
"cost_tag_keys": data_source_vo.cost_tag_keys,
"cost_additional_info_keys": data_source_vo.cost_additional_info_keys,
"cost_data_keys": data_source_vo.cost_data_keys,
"data_source_account_count": data_source_vo.data_source_account_count,
"connected_workspace_count": data_source_vo.connected_workspace_count,
"domain_id": data_source_vo.domain_id,
"created_at": utils.datetime_to_iso8601(data_source_vo.created_at),
"last_synchronized_at": utils.datetime_to_iso8601(
data_source_vo.last_synchronized_at
),
}
)

return data_source_pb2.DataSourceInfo(**info)


def DataSourcesInfo(data_source_vos, total_count, **kwargs):
return data_source_pb2.DataSourcesInfo(
results=list(map(functools.partial(DataSourceInfo, **kwargs), data_source_vos)),
total_count=total_count,
)
Loading
Loading