mirror of
https://github.com/jeessy2/ddns-go.git
synced 2025-10-20 15:33:46 +08:00
refactor(dns/traffic_route): Reconstruct the DNS resolution service of Volcengine (#1472)
reconstruct the dns resolution service of volcengine. Signed-off-by: LHSFK <lhsfk@141499.xyz>
This commit is contained in:
@ -2,85 +2,70 @@ package dns
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"github.com/jeessy2/ddns-go/v6/config"
|
||||
"github.com/jeessy2/ddns-go/v6/util"
|
||||
)
|
||||
|
||||
const (
|
||||
trafficRouteEndpoint = "https://open.volcengineapi.com"
|
||||
trafficRouteVersion = "2018-08-01"
|
||||
)
|
||||
|
||||
// TrafficRoute trafficRoute
|
||||
// TrafficRoute 火山引擎DNS服务
|
||||
type TrafficRoute struct {
|
||||
DNS config.DNS
|
||||
Domains config.Domains
|
||||
TTL int
|
||||
}
|
||||
|
||||
// TrafficRouteRecord record
|
||||
// TrafficRouteMeta 解析记录
|
||||
type TrafficRouteMeta struct {
|
||||
ZID int `json:"ZID"`
|
||||
RecordID string `json:"RecordID"` // 需要更新的解析记录的 ID
|
||||
PQDN string `json:"PQDN"` // 解析记录所包含的主机名
|
||||
Host string `json:"Host"` // 主机记录,即子域名的域名前缀
|
||||
TTL int `json:"TTL"` // 解析记录的过期时间
|
||||
Type string `json:"Type"` // 解析记录的类型
|
||||
Line string `json:"Line"` // 解析记录对应的线路代号, 一般为default
|
||||
Value string `json:"Value"` // 解析记录的记录值
|
||||
ZID int `json:"ZID"` // 域名ID
|
||||
RecordID string `json:"RecordID"` // 解析记录ID
|
||||
Host string `json:"Host"` // 主机记录
|
||||
Type string `json:"Type"` // 记录类型
|
||||
Value string `json:"Value"` // 记录值
|
||||
TTL int `json:"TTL"` // TTL值
|
||||
Line string `json:"Line"` // 解析线路
|
||||
}
|
||||
|
||||
// TrafficRouteZonesResp TrafficRoute zones返回结果
|
||||
type TrafficRouteZonesResp struct {
|
||||
Resp TrafficRouteRespMeta
|
||||
Total int
|
||||
Result struct {
|
||||
Zones []struct {
|
||||
ZID int
|
||||
ZoneName string
|
||||
RecordCount int
|
||||
}
|
||||
Total int
|
||||
}
|
||||
}
|
||||
|
||||
// TrafficRouteResp 修改/添加返回结果
|
||||
type TrafficRouteRecordsResp struct {
|
||||
Resp TrafficRouteRespMeta
|
||||
Result struct {
|
||||
TotalCount int
|
||||
Records []TrafficRouteMeta
|
||||
}
|
||||
}
|
||||
|
||||
// TrafficRouteStatus TrafficRoute 返回状态
|
||||
// https://www.volcengine.com/docs/6758/155089
|
||||
type TrafficRouteStatus struct {
|
||||
Resp TrafficRouteRespMeta
|
||||
Result struct {
|
||||
ZoneName string
|
||||
Status bool
|
||||
RecordCount int
|
||||
}
|
||||
}
|
||||
|
||||
// TrafficRoute 公共状态
|
||||
type TrafficRouteRespMeta struct {
|
||||
RequestId string
|
||||
Action string
|
||||
Version string
|
||||
Service string
|
||||
Region string
|
||||
// TrafficRouteResp API响应通用结构
|
||||
type TrafficRouteResp struct {
|
||||
ResponseMetadata struct {
|
||||
RequestId string `json:"RequestId"`
|
||||
Action string `json:"Action"`
|
||||
Version string `json:"Version"`
|
||||
Service string `json:"Service"`
|
||||
Region string `json:"Region"`
|
||||
Error struct {
|
||||
CodeN int
|
||||
Code string
|
||||
Message string
|
||||
MessageCN string
|
||||
Code string `json:"Code"`
|
||||
Message string `json:"Message"`
|
||||
} `json:"Error"`
|
||||
} `json:"ResponseMetadata"`
|
||||
Result struct {
|
||||
// 域名列表相关字段
|
||||
Zones []struct {
|
||||
ZID int `json:"ZID"`
|
||||
ZoneName string `json:"ZoneName"`
|
||||
RecordCount int `json:"RecordCount"`
|
||||
} `json:"Zones,omitempty"`
|
||||
Total int `json:"Total,omitempty"`
|
||||
|
||||
// 解析记录相关字段
|
||||
Records []TrafficRouteMeta `json:"Records,omitempty"`
|
||||
TotalCount int `json:"TotalCount,omitempty"`
|
||||
|
||||
// 创建/更新记录相关字段
|
||||
RecordID string `json:"RecordID,omitempty"`
|
||||
Status bool `json:"Status,omitempty"`
|
||||
} `json:"Result"`
|
||||
}
|
||||
|
||||
// TrafficRouteListZonesParams ListZones查询参数
|
||||
type TrafficRouteListZonesParams struct {
|
||||
Key string `json:"Key,omitempty"` // 获取包含特定关键字的域名(默认模糊搜索)
|
||||
}
|
||||
|
||||
// TrafficRouteListZonesResp
|
||||
type TrafficRouteListZonesResp struct {
|
||||
ZID int `json:"ZID"` // 域名ID
|
||||
}
|
||||
|
||||
func (tr *TrafficRoute) Init(dnsConf *config.DnsConfig, ipv4cache *util.IpCache, ipv6cache *util.IpCache) {
|
||||
@ -89,7 +74,6 @@ func (tr *TrafficRoute) Init(dnsConf *config.DnsConfig, ipv4cache *util.IpCache,
|
||||
tr.DNS = dnsConf.DNS
|
||||
tr.Domains.GetNewIp(dnsConf)
|
||||
if dnsConf.TTL == "" {
|
||||
// 默认 600s
|
||||
tr.TTL = 600
|
||||
} else {
|
||||
ttl, err := strconv.Atoi(dnsConf.TTL)
|
||||
@ -110,87 +94,85 @@ func (tr *TrafficRoute) AddUpdateDomainRecords() config.Domains {
|
||||
|
||||
func (tr *TrafficRoute) addUpdateDomainRecords(recordType string) {
|
||||
ipAddr, domains := tr.Domains.GetNewIpResult(recordType)
|
||||
|
||||
if ipAddr == "" {
|
||||
return
|
||||
}
|
||||
|
||||
for _, domain := range domains {
|
||||
// 获取域名列表
|
||||
ZoneResp, err := tr.listZones()
|
||||
resp := TrafficRouteListZonesResp{}
|
||||
tr.getZID(domain, &resp)
|
||||
zoneID := resp.ZID
|
||||
|
||||
if err != nil {
|
||||
util.Log("查询域名信息发生异常! %s", err)
|
||||
domain.UpdateStatus = config.UpdatedFailed
|
||||
return
|
||||
}
|
||||
|
||||
if ZoneResp.Result.Total == 0 {
|
||||
util.Log("在DNS服务商中未找到根域名: %s", domain.DomainName)
|
||||
domain.UpdateStatus = config.UpdatedFailed
|
||||
return
|
||||
}
|
||||
|
||||
zoneID := ZoneResp.Result.Zones[0].ZID
|
||||
|
||||
var recordResp TrafficRouteRecordsResp
|
||||
record := &TrafficRouteMeta{
|
||||
ZID: zoneID,
|
||||
}
|
||||
|
||||
err = tr.request(
|
||||
var recordResp TrafficRouteResp
|
||||
tr.request(
|
||||
"GET",
|
||||
"ListRecords",
|
||||
record,
|
||||
map[string][]string{"ZID": {strconv.Itoa(zoneID)}},
|
||||
&recordResp,
|
||||
)
|
||||
|
||||
found := false
|
||||
for _, record := range recordResp.Result.Records {
|
||||
if record.Type == recordType && record.Host == domain.GetSubDomain() {
|
||||
tr.modify(record, domain, ipAddr)
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
tr.create(zoneID, domain, recordType, ipAddr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// getZID 获取域名的ZID
|
||||
func (tr *TrafficRoute) getZID(domain *config.Domain, resp *TrafficRouteListZonesResp) {
|
||||
var result TrafficRouteResp
|
||||
err := tr.request(
|
||||
"GET",
|
||||
"ListZones",
|
||||
map[string][]string{"Key": {domain.DomainName}},
|
||||
&result,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
util.Log("查询域名信息发生异常! %s", err)
|
||||
domain.UpdateStatus = config.UpdatedFailed
|
||||
return
|
||||
}
|
||||
|
||||
if recordResp.Result.Records == nil {
|
||||
util.Log("查询域名信息发生异常! %s", recordResp.Resp.Error.Message)
|
||||
if len(result.Result.Zones) == 0 {
|
||||
util.Log("在DNS服务商中未找到域名: %s", domain.DomainName)
|
||||
domain.UpdateStatus = config.UpdatedFailed
|
||||
return
|
||||
}
|
||||
|
||||
find := false
|
||||
for _, record := range recordResp.Result.Records {
|
||||
if record.Type == recordType {
|
||||
// 更新
|
||||
tr.modify(record, zoneID, domain, recordType, ipAddr)
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !find {
|
||||
// 新增
|
||||
tr.create(zoneID, domain, recordType, ipAddr)
|
||||
for _, zone := range result.Result.Zones {
|
||||
if zone.ZoneName == domain.DomainName {
|
||||
resp.ZID = zone.ZID
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create 添加记录
|
||||
// CreateRecord https://www.volcengine.com/docs/6758/155104
|
||||
func (tr *TrafficRoute) create(zoneID int, domain *config.Domain, recordType string, ipAddr string) {
|
||||
// create 添加解析记录
|
||||
func (tr *TrafficRoute) create(zoneID int, domain *config.Domain, recordType, ipAddr string) {
|
||||
record := &TrafficRouteMeta{
|
||||
ZID: zoneID,
|
||||
Host: domain.GetSubDomain(),
|
||||
Type: recordType,
|
||||
Value: ipAddr,
|
||||
TTL: tr.TTL,
|
||||
Line: "default",
|
||||
}
|
||||
|
||||
var status TrafficRouteStatus
|
||||
var result TrafficRouteResp
|
||||
err := tr.request(
|
||||
"POST",
|
||||
"CreateRecord",
|
||||
record,
|
||||
&status,
|
||||
&result,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
@ -199,35 +181,32 @@ func (tr *TrafficRoute) create(zoneID int, domain *config.Domain, recordType str
|
||||
return
|
||||
}
|
||||
|
||||
if reflect.ValueOf(status.Result.Status).IsZero() {
|
||||
if result.ResponseMetadata.Error.Code == "" {
|
||||
util.Log("新增域名解析 %s 成功! IP: %s", domain, ipAddr)
|
||||
domain.UpdateStatus = config.UpdatedSuccess
|
||||
} else {
|
||||
util.Log("新增域名解析 %s 失败! 异常信息: %s, ", domain, status.Resp.Error.Message)
|
||||
util.Log("新增域名解析 %s 失败! 异常信息: %s", domain, result.ResponseMetadata.Error.Message)
|
||||
domain.UpdateStatus = config.UpdatedFailed
|
||||
}
|
||||
}
|
||||
|
||||
// update 修改记录
|
||||
// UpdateRecord https://www.volcengine.com/docs/6758/155106
|
||||
func (tr *TrafficRoute) modify(record TrafficRouteMeta, zoneID int, domain *config.Domain, recordType string, ipAddr string) {
|
||||
// 相同不修改
|
||||
if (record.Value == ipAddr) && (record.Host == domain.GetSubDomain()) {
|
||||
util.Log("你的IP %s 没有变化, 域名 %s", ipAddr, domain)
|
||||
// modify 修改解析记录
|
||||
func (tr *TrafficRoute) modify(record TrafficRouteMeta, domain *config.Domain, ipAddr string) {
|
||||
if record.Value == ipAddr {
|
||||
util.Log("IP %s 没有变化,域名 %s", ipAddr, domain)
|
||||
domain.UpdateStatus = config.UpdatedSuccess
|
||||
return
|
||||
}
|
||||
var status TrafficRouteStatus
|
||||
record.Host = domain.GetSubDomain()
|
||||
record.Type = recordType
|
||||
// record.Line = "default"
|
||||
|
||||
record.Value = ipAddr
|
||||
record.TTL = tr.TTL
|
||||
|
||||
var result TrafficRouteResp
|
||||
err := tr.request(
|
||||
"POST",
|
||||
"UpdateRecord",
|
||||
record,
|
||||
&status,
|
||||
&result,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
@ -236,60 +215,67 @@ func (tr *TrafficRoute) modify(record TrafficRouteMeta, zoneID int, domain *conf
|
||||
return
|
||||
}
|
||||
|
||||
if reflect.ValueOf(status.Result.Status).IsZero() {
|
||||
if result.ResponseMetadata.Error.Code == "" {
|
||||
util.Log("更新域名解析 %s 成功! IP: %s", domain, ipAddr)
|
||||
domain.UpdateStatus = config.UpdatedSuccess
|
||||
} else {
|
||||
util.Log("更新域名解析 %s 失败! 异常信息: %s, ", domain, status.Resp.Error.Message)
|
||||
util.Log("更新域名解析 %s 失败! 异常信息: %s", domain, result.ResponseMetadata.Error.Message)
|
||||
domain.UpdateStatus = config.UpdatedFailed
|
||||
}
|
||||
}
|
||||
|
||||
// List 获得域名记录列表
|
||||
// ListZones https://www.volcengine.com/docs/6758/155100
|
||||
func (tr *TrafficRoute) listZones() (result TrafficRouteZonesResp, err error) {
|
||||
record := TrafficRouteMeta{}
|
||||
// parseRequestParams 解析请求参数
|
||||
func (tr *TrafficRoute) parseRequestParams(action string, data interface{}) (queryParams map[string][]string, jsonStr []byte, err error) {
|
||||
queryParams = make(map[string][]string)
|
||||
|
||||
err = tr.request(
|
||||
"GET",
|
||||
"ListZones",
|
||||
record,
|
||||
&result,
|
||||
)
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
// request 统一请求接口
|
||||
func (tr *TrafficRoute) request(method string, action string, data interface{}, result interface{}) (err error) {
|
||||
jsonStr := make([]byte, 0)
|
||||
switch v := data.(type) {
|
||||
case map[string][]string:
|
||||
queryParams = v
|
||||
jsonStr = []byte{}
|
||||
case *TrafficRouteMeta:
|
||||
jsonStr, _ = json.Marshal(v)
|
||||
default:
|
||||
if data != nil {
|
||||
jsonStr, _ = json.Marshal(data)
|
||||
}
|
||||
}
|
||||
|
||||
// 根据不同action处理参数
|
||||
switch action {
|
||||
case "ListZones":
|
||||
if len(queryParams) == 0 && len(jsonStr) > 0 {
|
||||
var params TrafficRouteListZonesParams
|
||||
if err = json.Unmarshal(jsonStr, ¶ms); err == nil && params.Key != "" {
|
||||
queryParams["Key"] = []string{params.Key}
|
||||
}
|
||||
jsonStr = []byte{}
|
||||
}
|
||||
case "ListRecords":
|
||||
if len(queryParams) == 0 && len(jsonStr) > 0 {
|
||||
var params TrafficRouteListZonesResp
|
||||
if err = json.Unmarshal(jsonStr, ¶ms); err == nil && params.ZID != 0 {
|
||||
queryParams["ZID"] = []string{strconv.Itoa(params.ZID)}
|
||||
}
|
||||
jsonStr = []byte{}
|
||||
}
|
||||
}
|
||||
|
||||
var req *http.Request
|
||||
// updateZoneResult, err := requestDNS("POST", map[string][]string{}, map[string]string{}, secretId, secretKey, action, body)
|
||||
if action != "ListRecords" {
|
||||
req, err = util.TrafficRouteSigner(method, map[string][]string{}, map[string]string{}, tr.DNS.ID, tr.DNS.Secret, action, jsonStr)
|
||||
} else {
|
||||
var QueryParamConv TrafficRouteMeta
|
||||
jsonRes := json.Unmarshal(jsonStr, &QueryParamConv)
|
||||
if jsonRes != nil {
|
||||
util.Log("%v", jsonRes)
|
||||
return
|
||||
}
|
||||
zoneID := strconv.Itoa(QueryParamConv.ZID)
|
||||
QueryParam := map[string][]string{"ZID": []string{zoneID}}
|
||||
req, err = util.TrafficRouteSigner(method, QueryParam, map[string]string{}, tr.DNS.ID, tr.DNS.Secret, action, []byte{})
|
||||
|
||||
// request 统一请求接口
|
||||
func (tr *TrafficRoute) request(method string, action string, data interface{}, result interface{}) error {
|
||||
queryParams, jsonStr, err := tr.parseRequestParams(action, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req, err := util.TrafficRouteSigner(method, queryParams, map[string]string{}, tr.DNS.ID, tr.DNS.Secret, action, jsonStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client := util.CreateHTTPClient()
|
||||
resp, err := client.Do(req)
|
||||
err = util.GetHTTPResponse(resp, err, result)
|
||||
|
||||
return err
|
||||
return util.GetHTTPResponse(resp, err, result)
|
||||
}
|
||||
|
Reference in New Issue
Block a user