fix: 完善多云同步验证与实例统计

- 修复华为云签名、账单字段与区域映射缓存
- 按真实云实例更新账号服务器数并补充并发测试
This commit is contained in:
Logan.Li committed 2026-07-29 06:35:54 +08:00
1 parent 132fe9ba97
commit 9b895efee3
6 files changed
+226 -64

No files matched your search

+26 -12
View File
@@ -8,15 +8,20 @@ import (
"net/http"
"sort"
"strings"
"sync"
"time"
)
// HuaweiProvider 通过华为云 AK/SK 签名 API 同步项目区域与 ECS 实例。 // Logan.Li
type HuaweiProvider struct{ accessKey, secretKey string }
type HuaweiProvider struct {
accessKey, secretKey string
regionMu sync.RWMutex
regionByProject map[string]string
}
// NewHuaweiProvider 创建华为云 Provider。 // Logan.Li
func NewHuaweiProvider(accessKey, secretKey string) *HuaweiProvider {
return &HuaweiProvider{accessKey, secretKey}
return &HuaweiProvider{accessKey: accessKey, secretKey: secretKey, regionByProject: make(map[string]string)}
}
// Name 返回华为云厂商标识。 // Logan.Li
@@ -32,7 +37,11 @@ func (p *HuaweiProvider) signedGet(rawURL, _ string) ([]byte, error) {
host := u.URL.Host
canonicalHeaders := "host:" + host + "\n" + "x-sdk-date:" + now + "\n"
signedHeaders := "host;x-sdk-date"
canonicalRequest := "GET\n" + u.URL.EscapedPath() + "\n" + u.URL.Query().Encode() + "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + sha256Hex("")
canonicalURI := u.URL.EscapedPath()
if !strings.HasSuffix(canonicalURI, "/") {
canonicalURI += "/"
}
canonicalRequest := "GET\n" + canonicalURI + "\n" + u.URL.Query().Encode() + "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + sha256Hex("")
stringToSign := "SDK-HMAC-SHA256\n" + now + "\n" + sha256Hex(canonicalRequest)
signature := hex.EncodeToString(hmacSHA256([]byte(p.secretKey), stringToSign))
u.Header.Set("X-Sdk-Date", now)
@@ -68,28 +77,33 @@ func (p *HuaweiProvider) ListRegions() ([]CloudRegion, error) {
return nil, fmt.Errorf("解析华为云区域响应失败: %w", err)
}
regions := []CloudRegion{}
regionByProject := make(map[string]string, len(result.Projects))
for _, project := range result.Projects {
if project.ID == "" || project.Name == "" {
continue
}
regions = append(regions, CloudRegion{RegionID: project.ID, LocalName: project.Name, Endpoint: "https://ecs." + project.Name + ".myhuaweicloud.com", Status: "active"})
regionByProject[project.ID] = project.Name
}
p.regionMu.Lock()
p.regionByProject = regionByProject
p.regionMu.Unlock()
sort.Slice(regions, func(i, j int) bool { return regions[i].LocalName < regions[j].LocalName })
return regions, nil
}
// ListInstances 获取指定华为云项目中的 ECS 实例。 // Logan.Li
func (p *HuaweiProvider) ListInstances(projectID string) ([]CloudInstance, error) {
regions, err := p.ListRegions()
if err != nil {
return nil, err
}
regionName := ""
for _, region := range regions {
if region.RegionID == projectID {
regionName = region.LocalName
break
p.regionMu.RLock()
regionName := p.regionByProject[projectID]
p.regionMu.RUnlock()
if regionName == "" {
if _, err := p.ListRegions(); err != nil {
return nil, err
}
p.regionMu.RLock()
regionName = p.regionByProject[projectID]
p.regionMu.RUnlock()
}
if regionName == "" {
return nil, fmt.Errorf("未找到华为云项目 %s", projectID)