初始提交:OCI 面板后端(含 GenAI 网关一期)
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
package oci
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/oracle/oci-go-sdk/v65/common"
|
||||
"github.com/oracle/oci-go-sdk/v65/usageapi"
|
||||
)
|
||||
|
||||
// CostQuery 是一次成本/用量分析的条件。
|
||||
type CostQuery struct {
|
||||
StartTime time.Time
|
||||
EndTime time.Time
|
||||
Granularity string // DAILY / MONTHLY
|
||||
QueryType string // COST / USAGE
|
||||
GroupBy string // service / skuName / region 等维度
|
||||
}
|
||||
|
||||
// CostItem 是一个时间桶内某分组维度的成本或用量。
|
||||
type CostItem struct {
|
||||
TimeStart *time.Time `json:"timeStart"`
|
||||
GroupValue string `json:"groupValue"`
|
||||
ComputedAmount float32 `json:"computedAmount"`
|
||||
ComputedQuantity float32 `json:"computedQuantity"`
|
||||
Currency string `json:"currency"`
|
||||
Unit string `json:"unit,omitempty"`
|
||||
}
|
||||
|
||||
// SummarizeCosts 实现 Client:调用 Usage API 汇总租户成本或用量。
|
||||
func (c *RealClient) SummarizeCosts(ctx context.Context, cred Credentials, q CostQuery) ([]CostItem, error) {
|
||||
uc, err := usageapi.NewUsageapiClientWithConfigurationProvider(provider(cred))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("new usageapi client: %w", err)
|
||||
}
|
||||
applyProxy(&uc.BaseClient, cred)
|
||||
details, err := buildUsageDetails(cred.TenancyOCID, q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var items []CostItem
|
||||
var page *string
|
||||
for {
|
||||
resp, err := uc.RequestSummarizedUsages(ctx, usageapi.RequestSummarizedUsagesRequest{
|
||||
RequestSummarizedUsagesDetails: details,
|
||||
Page: page,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("request summarized usages: %w", err)
|
||||
}
|
||||
for _, item := range resp.Items {
|
||||
items = append(items, toCostItem(item, q.GroupBy))
|
||||
}
|
||||
if resp.OpcNextPage == nil {
|
||||
return orEmpty(items), nil
|
||||
}
|
||||
page = resp.OpcNextPage
|
||||
}
|
||||
}
|
||||
|
||||
func buildUsageDetails(tenancyOCID string, q CostQuery) (usageapi.RequestSummarizedUsagesDetails, error) {
|
||||
granularity, ok := usageapi.GetMappingRequestSummarizedUsagesDetailsGranularityEnum(strings.ToUpper(q.Granularity))
|
||||
if !ok {
|
||||
return usageapi.RequestSummarizedUsagesDetails{}, fmt.Errorf("cost query: unsupported granularity %q", q.Granularity)
|
||||
}
|
||||
queryType, ok := usageapi.GetMappingRequestSummarizedUsagesDetailsQueryTypeEnum(strings.ToUpper(q.QueryType))
|
||||
if !ok {
|
||||
return usageapi.RequestSummarizedUsagesDetails{}, fmt.Errorf("cost query: unsupported queryType %q", q.QueryType)
|
||||
}
|
||||
return usageapi.RequestSummarizedUsagesDetails{
|
||||
TenantId: &tenancyOCID,
|
||||
TimeUsageStarted: &common.SDKTime{Time: q.StartTime},
|
||||
TimeUsageEnded: &common.SDKTime{Time: q.EndTime},
|
||||
Granularity: granularity,
|
||||
QueryType: queryType,
|
||||
GroupBy: []string{q.GroupBy},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// toCostItem 把响应条目转为本地 DTO,分组值按 groupBy 维度取对应字段。
|
||||
func toCostItem(item usageapi.UsageSummary, groupBy string) CostItem {
|
||||
out := CostItem{
|
||||
Currency: deref(item.Currency),
|
||||
Unit: deref(item.Unit),
|
||||
}
|
||||
if item.TimeUsageStarted != nil {
|
||||
out.TimeStart = &item.TimeUsageStarted.Time
|
||||
}
|
||||
if item.ComputedAmount != nil {
|
||||
out.ComputedAmount = *item.ComputedAmount
|
||||
}
|
||||
if item.ComputedQuantity != nil {
|
||||
out.ComputedQuantity = *item.ComputedQuantity
|
||||
}
|
||||
switch strings.ToLower(groupBy) {
|
||||
case "skuname":
|
||||
out.GroupValue = deref(item.SkuName)
|
||||
case "region":
|
||||
out.GroupValue = deref(item.Region)
|
||||
case "compartmentname":
|
||||
out.GroupValue = deref(item.CompartmentName)
|
||||
default:
|
||||
out.GroupValue = deref(item.Service)
|
||||
}
|
||||
return out
|
||||
}
|
||||
Reference in New Issue
Block a user