Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,7 @@ def create_task(self) -> list:
return tasks

def _create_budget_utilization_rate_update_task(self):
from spaceone.core import model

model.init_all(False)
current_day = datetime.now(timezone.utc).day
if (
current_day == self._budget_update_day
Expand Down
2 changes: 1 addition & 1 deletion src/spaceone/cost_analysis/manager/budget_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def push_budget_job_task(params: dict) -> None:
"locator": "SERVICE",
"name": "BudgetService",
"metadata": {"token": token},
"method": "update_budget_utilization_rate",
"method": "init_monthly_budget_info",
"params": {"params": params},
}
],
Expand Down
38 changes: 17 additions & 21 deletions src/spaceone/cost_analysis/manager/budget_usage_manager.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import logging
from datetime import datetime, timezone
from typing import Union

from dateutil.rrule import rrule, MONTHLY

from spaceone.core import config
Expand Down Expand Up @@ -105,12 +103,12 @@ def notify_budget_usage(self, budget_vo: Budget) -> None:
budget_id = budget_vo.budget_id
workspace_id = budget_vo.workspace_id
domain_id = budget_vo.domain_id
current_month = datetime.now(timezone.utc).strftime("%Y-%m")
updated_plans = []
is_changed = False
notification = budget_vo.notification

plans = notification.plans or []
current_month = datetime.now(timezone.utc).strftime("%Y-%m")
updated_plans = []
is_changed = False

for plan in plans:

Expand All @@ -120,8 +118,10 @@ def notify_budget_usage(self, budget_vo: Budget) -> None:
)
continue

unit = plan.unit
threshold = plan.threshold
plan_info = plan.to_dict()

unit = plan_info["unit"]
threshold = plan_info["threshold"]
is_notify = False

if budget_vo.time_unit == "TOTAL":
Expand Down Expand Up @@ -157,6 +157,7 @@ def notify_budget_usage(self, budget_vo: Budget) -> None:
continue

budget_percentage = budget_vo.utilization_rate
total_budget_usage = round(total_budget_usage, 2)

if unit == "PERCENT":
if budget_percentage > threshold:
Expand All @@ -166,28 +167,23 @@ def notify_budget_usage(self, budget_vo: Budget) -> None:
_LOGGER.debug(
f"[notify_budget_usage] notify event: {budget_id}, current month: {current_month} (plan: {plan.to_dict()})"
)

try:
self._notify_message(
budget_vo,
total_budget_usage,
budget_percentage,
threshold,
)

updated_plans.append(
{
"threshold": threshold,
"unit": unit,
"notified": True,
}
)
plan_info["notified"] = True

except Exception as e:
_LOGGER.error(
f"[notify_budget_usage] Failed to notify message ({budget_id}): {e}",
f"[notify_budget_usage] Failed to notify message ({budget_id}): plan: {plan_info}, {e}",
exc_info=True,
)
plan_info["notified"] = False
finally:
updated_plans.append(plan_info)
else:
if unit == "PERCENT":
_LOGGER.debug(
Expand All @@ -200,7 +196,7 @@ def notify_budget_usage(self, budget_vo: Budget) -> None:
f"(usage cost: {total_budget_usage}, threshold: {threshold})"
)

updated_plans.append(plan.to_dict())
updated_plans.append(plan_info)

if is_changed:
notification.plans = updated_plans
Expand All @@ -216,9 +212,9 @@ def _notify_message(
self,
budget_vo: Budget,
total_budget_usage: float,
budget_percentage,
threshold,
):
budget_percentage: float,
threshold: int,
) -> None:

if not self.email_mgr:
self.email_mgr = EmailManager()
Expand Down
2 changes: 1 addition & 1 deletion src/spaceone/cost_analysis/manager/email_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
},
"ja": {
"cost_report": "費用レポートが確認のために準備されました。",
"budget_usage_alert": "",
},
}

Expand Down Expand Up @@ -97,6 +96,7 @@ def send_budget_usage_alert_email(
usage_rate=budget_percentage,
today_date=today_date,
budget_detail_link=console_link,
currency=budget_vo.currency,
)

subject = f"[{service_name}] {language_map_info['budget_usage_alert'].format(budget_name=budget_vo.name, threshold=threshold)}"
Expand Down
1 change: 0 additions & 1 deletion src/spaceone/cost_analysis/model/budget/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ class Budget(MongoModel):
"workspace_id",
"project_id",
"name",
"budget_id",
"time_unit",
"service_account_id",
],
Expand Down
21 changes: 15 additions & 6 deletions src/spaceone/cost_analysis/service/budget_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ def stat(self, params: BudgetStatQueryRequest) -> dict:

@transaction(exclude=["authentication", "authorization", "mutation"])
@check_required(["domain_id"])
def update_budget_utilization_rate(self, params: dict) -> None:
def init_monthly_budget_info(self, params: dict) -> None:
"""
Args:
params (dict): {
Expand All @@ -432,17 +432,26 @@ def update_budget_utilization_rate(self, params: dict) -> None:
{"k": "end", "v": current_month, "o": "gte"},
]
}
_LOGGER.debug(f"[update_budget_utilization_rate] query_filter: {query_filter}")
_LOGGER.debug(f"[init_monthly_budget_info] query_filter: {query_filter}")
budget_vos, _ = self.budget_mgr.list_budgets(query_filter)

for budget_vo in budget_vos:
utilization_rate = 0
planned_limits = budget_vo.planned_limits or []
notification = budget_vo.notification.to_dict() or {}

budget_limit = self._get_budget_limit_from_planned_limits(planned_limits)
notification = self._reset_plans_from_notification(budget_vo.notification)
notification = self._reset_plans_from_notification(notification)

budget_usage_vos = self.budget_usage_mgr.filter_budget_usages(
domain_id=domain_id, budget_id=budget_vo.budget_id, date=current_month
)

if budget_limit > 0 and (budget_usage_vo := budget_usage_vos[0]):
utilization_rate = budget_usage_vo.cost / budget_limit * 100

update_params = {
"utilization_rate": 0,
"utilization_rate": utilization_rate,
"limit": budget_limit,
"notification": notification,
}
Expand All @@ -462,8 +471,8 @@ def _check_time_period(start: str, end: str, budget_year: str = None) -> None:
raise ERROR_INVALID_TIME_RANGE(start=start, end=end)

if budget_year:
start_year = start[:4]
end_year = end[:4]
start_year = start.split("-")[0]
end_year = end.split("-")[0]
if start_year != budget_year or end_year != budget_year:
raise ERROR_INVALID_PARAMETER(
key="budget_year",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@
• Budget Name: {{budget_name}}<br>
• Budget Target: {{budget_target}}<br>
• Budget Amount: {{budget_amount}} ({{budget_cycle}})<br>
• Actual Cost: {{actual_cost}} ({{usage_rate}}%)<br>
• Actual Cost: {{actual_cost}} {{currency}} ({{usage_rate}}%)<br>
• Alert Date: {{today_date}}<br><br>
</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@
• 예산명: {{budget_name}}<br>
• 예산 타겟: {{budget_target}}<br>
• 예산: {{budget_amount}} ({{budget_cycle}})<br>
• 실 사용 금액: {{actual_cost}} ({{usage_rate}}%)<br>
• 실 사용 금액: {{actual_cost}} {{currency}} ({{usage_rate}}%)<br>
• 알림 일자: {{today_date}}<br><br>
</span>
</div>
Expand Down
Loading