feat: 为华为云添加自定义参数支持 (#1464)

* feat(huaweicloud): 为华为云添加自定义参数支持
This commit is contained in:
xfl12345
2025-05-18 20:06:31 +08:00
committed by GitHub
parent bd82cf9043
commit 20bdfc05e8
3 changed files with 122 additions and 41 deletions

View File

@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"strconv"
"github.com/jeessy2/ddns-go/v6/config"
@ -46,6 +47,7 @@ type HuaweicloudRecordsets struct {
Type string `json:"type"`
TTL int `json:"ttl"`
Records []string `json:"records"`
Weight int `json:"weight"`
}
// Init 初始化
@ -82,38 +84,81 @@ func (hw *Huaweicloud) addUpdateDomainRecords(recordType string) {
}
for _, domain := range domains {
customParams := domain.GetCustomParams()
params := url.Values{}
params.Set("name", domain.String())
params.Set("type", recordType)
var records HuaweicloudRecordsResp
// 如果有精准匹配
// 详见 查询记录集 https://support.huaweicloud.com/api-dns/dns_api_64002.html
if customParams.Has("zone_id") && customParams.Has("recordset_id") {
var record HuaweicloudRecordsets
err := hw.request(
"GET",
fmt.Sprintf(huaweicloudEndpoint+"/v2.1/zones/%s/recordsets/%s", customParams.Get("zone_id"), customParams.Get("recordset_id")),
params,
&record,
)
err := hw.request(
"GET",
fmt.Sprintf(huaweicloudEndpoint+"/v2/recordsets?type=%s&name=%s", recordType, domain),
nil,
&records,
)
if err != nil {
util.Log("查询域名信息发生异常! %s", err)
domain.UpdateStatus = config.UpdatedFailed
return
}
if err != nil {
util.Log("查询域名信息发生异常! %s", err)
domain.UpdateStatus = config.UpdatedFailed
return
}
// 更新
hw.modify(record, domain, ipAddr)
find := false
for _, record := range records.Recordsets {
// 名称相同才更新。华为云默认是模糊搜索
if record.Name == domain.String()+"." {
// 更新
hw.modify(record, domain, ipAddr)
find = true
break
} else { // 没有精准匹配,则支持更多的查询参数。详见 查询租户记录集列表 https://support.huaweicloud.com/api-dns/dns_api_64003.html
// 复制所有自定义参数
util.CopyUrlParams(customParams, params, nil)
// 参数名修正
if params.Has("recordset_id") {
params.Set("id", params.Get("recordset_id"))
params.Del("recordset_id")
}
var records HuaweicloudRecordsResp
err := hw.request(
"GET",
huaweicloudEndpoint+"/v2.1/recordsets",
params,
&records,
)
if err != nil {
util.Log("查询域名信息发生异常! %s", err)
domain.UpdateStatus = config.UpdatedFailed
return
}
find := false
for _, record := range records.Recordsets {
// 名称相同才更新。华为云默认是模糊搜索
if record.Name == domain.String()+"." {
// 更新
hw.modify(record, domain, ipAddr)
find = true
break
}
}
if !find {
thIdParamName := ""
if customParams.Has("id") {
thIdParamName = "id"
} else if customParams.Has("recordset_id") {
thIdParamName = "recordset_id"
}
if thIdParamName != "" {
util.Log("域名 %s 解析未找到,且因添加了参数 %s=%s 导致无法创建。本次更新已被忽略", domain, thIdParamName, customParams.Get(thIdParamName))
} else {
// 新增
hw.create(domain, recordType, ipAddr)
}
}
}
if !find {
// 新增
hw.create(domain, recordType, ipAddr)
}
}
}
@ -145,11 +190,12 @@ func (hw *Huaweicloud) create(domain *config.Domain, recordType string, ipAddr s
Name: domain.String() + ".",
Records: []string{ipAddr},
TTL: hw.TTL,
Weight: 1,
}
var result HuaweicloudRecordsets
err = hw.request(
"POST",
fmt.Sprintf(huaweicloudEndpoint+"/v2/zones/%s/recordsets", zoneID),
fmt.Sprintf(huaweicloudEndpoint+"/v2.1/zones/%s/recordsets", zoneID),
record,
&result,
)
@ -178,7 +224,9 @@ func (hw *Huaweicloud) modify(record HuaweicloudRecordsets, domain *config.Domai
return
}
var request map[string]interface{} = make(map[string]interface{})
var request = make(map[string]interface{})
request["name"] = record.Name
request["type"] = record.Type
request["records"] = []string{ipAddr}
request["ttl"] = hw.TTL
@ -186,7 +234,7 @@ func (hw *Huaweicloud) modify(record HuaweicloudRecordsets, domain *config.Domai
err := hw.request(
"PUT",
fmt.Sprintf(huaweicloudEndpoint+"/v2/zones/%s/recordsets/%s", record.ZoneID, record.ID),
fmt.Sprintf(huaweicloudEndpoint+"/v2.1/zones/%s/recordsets/%s", record.ZoneID, record.ID),
&request,
&result,
)
@ -210,8 +258,8 @@ func (hw *Huaweicloud) modify(record HuaweicloudRecordsets, domain *config.Domai
func (hw *Huaweicloud) getZones(domain *config.Domain) (result HuaweicloudZonesResp, err error) {
err = hw.request(
"GET",
fmt.Sprintf(huaweicloudEndpoint+"/v2/zones?name=%s", domain.DomainName),
nil,
huaweicloudEndpoint+"/v2/zones",
url.Values{"name": []string{domain.DomainName}},
&result,
)
@ -219,18 +267,32 @@ func (hw *Huaweicloud) getZones(domain *config.Domain) (result HuaweicloudZonesR
}
// request 统一请求接口
func (hw *Huaweicloud) request(method string, url string, data interface{}, result interface{}) (err error) {
jsonStr := make([]byte, 0)
if data != nil {
jsonStr, _ = json.Marshal(data)
}
req, err := http.NewRequest(
method,
url,
bytes.NewBuffer(jsonStr),
func (hw *Huaweicloud) request(method string, urlString string, data interface{}, result interface{}) (err error) {
var (
req *http.Request
)
if method == "GET" {
req, err = http.NewRequest(
method,
urlString,
bytes.NewBuffer(nil),
)
req.URL.RawQuery = data.(url.Values).Encode()
} else {
jsonStr := make([]byte, 0)
if data != nil {
jsonStr, _ = json.Marshal(data)
}
req, err = http.NewRequest(
method,
urlString,
bytes.NewBuffer(jsonStr),
)
}
if err != nil {
return
}

18
util/copy_url_params.go Normal file
View File

@ -0,0 +1,18 @@
package util
import "net/url"
func CopyUrlParams(src url.Values, dest url.Values, keys []string) {
if keys == nil || len(keys) == 0 {
for key := range src {
dest.Set(key, src.Get(key))
}
} else {
for _, key := range keys {
val := src.Get(key)
if val != "" {
dest.Set(key, val)
}
}
}
}

View File

@ -79,6 +79,7 @@ func init() {
// domains
message.SetString(language.English, "域名: %s 不正确", "The domain %s is incorrect")
message.SetString(language.English, "域名: %s 解析失败", "The domain %s resolution failed")
message.SetString(language.English, "域名 %s 解析未找到,且因添加了参数 %s=%s 导致无法创建。本次更新已被忽略", "DNS resolution for domain %s was not found, and the creation failed due to the added parameter %s=%s. This update has been ignored.")
message.SetString(language.English, "IPv6未改变, 将等待 %d 次后与DNS服务商进行比对", "IPv6 has not changed, will wait %d times to compare with DNS provider")
message.SetString(language.English, "IPv4未改变, 将等待 %d 次后与DNS服务商进行比对", "IPv4 has not changed, will wait %d times to compare with DNS provider")