初始提交:OCI 面板后端(含 GenAI 网关一期)
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"oci-portal/internal/oci"
|
||||
)
|
||||
|
||||
// maxUsageWindowDays 限制流量/成本查询窗口,避免拉取超大区间。
|
||||
const maxUsageWindowDays = 366
|
||||
|
||||
// InstanceTraffic 查询实例近 days 天的进出流量(按天聚合)。
|
||||
func (s *OciConfigService) InstanceTraffic(ctx context.Context, id uint, region, instanceID string, days int) (oci.InstanceTraffic, error) {
|
||||
if days <= 0 {
|
||||
days = 30
|
||||
}
|
||||
if days > maxUsageWindowDays {
|
||||
return oci.InstanceTraffic{}, fmt.Errorf("instance traffic: days must be within %d", maxUsageWindowDays)
|
||||
}
|
||||
cred, err := s.credentialsByID(ctx, id)
|
||||
if err != nil {
|
||||
return oci.InstanceTraffic{}, err
|
||||
}
|
||||
end := time.Now().UTC().Truncate(time.Hour).Add(time.Hour)
|
||||
return s.client.SummarizeInstanceTraffic(ctx, cred, oci.TrafficQuery{
|
||||
Region: region,
|
||||
InstanceID: instanceID,
|
||||
StartTime: end.AddDate(0, 0, -days),
|
||||
EndTime: end,
|
||||
})
|
||||
}
|
||||
|
||||
// Costs 汇总租户成本或用量;时间缺省为最近 30 天,起止按粒度对齐。
|
||||
func (s *OciConfigService) Costs(ctx context.Context, id uint, q oci.CostQuery) ([]oci.CostItem, error) {
|
||||
applyCostDefaults(&q)
|
||||
if q.EndTime.Sub(q.StartTime) <= 0 {
|
||||
return nil, fmt.Errorf("costs: endTime must be after startTime")
|
||||
}
|
||||
if q.EndTime.Sub(q.StartTime) > maxUsageWindowDays*24*time.Hour {
|
||||
return nil, fmt.Errorf("costs: window must be within %d days", maxUsageWindowDays)
|
||||
}
|
||||
cred, err := s.credentialsByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s.client.SummarizeCosts(ctx, cred, q)
|
||||
}
|
||||
|
||||
// applyCostDefaults 填充缺省值并把时间对齐到粒度边界(Usage API 要求)。
|
||||
func applyCostDefaults(q *oci.CostQuery) {
|
||||
if q.Granularity == "" {
|
||||
q.Granularity = "DAILY"
|
||||
}
|
||||
if q.QueryType == "" {
|
||||
q.QueryType = "COST"
|
||||
}
|
||||
if q.GroupBy == "" {
|
||||
q.GroupBy = "service"
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
if q.EndTime.IsZero() {
|
||||
q.EndTime = now
|
||||
}
|
||||
if q.StartTime.IsZero() {
|
||||
q.StartTime = q.EndTime.AddDate(0, 0, -30)
|
||||
}
|
||||
q.StartTime = alignDown(q.StartTime, q.Granularity)
|
||||
// endTime 为开区间,向上对齐到粒度边界以覆盖当天/当月
|
||||
q.EndTime = alignUp(q.EndTime, q.Granularity)
|
||||
}
|
||||
|
||||
func alignDown(t time.Time, granularity string) time.Time {
|
||||
t = t.UTC()
|
||||
if granularity == "MONTHLY" {
|
||||
return time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, time.UTC)
|
||||
}
|
||||
return t.Truncate(24 * time.Hour)
|
||||
}
|
||||
|
||||
func alignUp(t time.Time, granularity string) time.Time {
|
||||
down := alignDown(t, granularity)
|
||||
if down.Equal(t.UTC()) {
|
||||
return down
|
||||
}
|
||||
if granularity == "MONTHLY" {
|
||||
return down.AddDate(0, 1, 0)
|
||||
}
|
||||
return down.AddDate(0, 0, 1)
|
||||
}
|
||||
Reference in New Issue
Block a user