mirror of
https://github.com/TeaOSLab/EdgeAPI.git
synced 2025-11-02 22:10:26 +08:00
294 lines
7.2 KiB
Go
294 lines
7.2 KiB
Go
package dnsclients
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
|
|
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
|
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
|
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
|
|
"github.com/aliyun/alibaba-cloud-sdk-go/services/alidns"
|
|
"github.com/iwind/TeaGo/maps"
|
|
"github.com/iwind/TeaGo/types"
|
|
)
|
|
|
|
// AliDNSProvider 阿里云服务商
|
|
type AliDNSProvider struct {
|
|
BaseProvider
|
|
|
|
ProviderId int64
|
|
|
|
accessKeyId string
|
|
accessKeySecret string
|
|
regionId string
|
|
}
|
|
|
|
// Auth 认证
|
|
func (this *AliDNSProvider) Auth(params maps.Map) error {
|
|
this.accessKeyId = params.GetString("accessKeyId")
|
|
this.accessKeySecret = params.GetString("accessKeySecret")
|
|
this.regionId = params.GetString("regionId")
|
|
|
|
if len(this.accessKeyId) == 0 {
|
|
return errors.New("'accessKeyId' should not be empty")
|
|
}
|
|
if len(this.accessKeySecret) == 0 {
|
|
return errors.New("'accessKeySecret' should not be empty")
|
|
}
|
|
|
|
if len(this.regionId) == 0 {
|
|
this.regionId = "cn-hangzhou"
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// MaskParams 对参数进行掩码
|
|
func (this *AliDNSProvider) MaskParams(params maps.Map) {
|
|
if params == nil {
|
|
return
|
|
}
|
|
params["accessKeySecret"] = MaskString(params.GetString("accessKeySecret"))
|
|
}
|
|
|
|
// GetDomains 获取所有域名列表
|
|
func (this *AliDNSProvider) GetDomains() (domains []string, err error) {
|
|
var pageNumber = 1
|
|
var size = 100
|
|
|
|
for {
|
|
var req = alidns.CreateDescribeDomainsRequest()
|
|
req.PageNumber = requests.NewInteger(pageNumber)
|
|
req.PageSize = requests.NewInteger(size)
|
|
var resp = alidns.CreateDescribeDomainsResponse()
|
|
err = this.doAPI(req, resp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, domain := range resp.Domains.Domain {
|
|
domains = append(domains, domain.DomainName)
|
|
}
|
|
|
|
pageNumber++
|
|
if int64((pageNumber-1)*size) >= resp.TotalCount {
|
|
break
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// GetRecords 获取域名列表
|
|
func (this *AliDNSProvider) GetRecords(domain string) (records []*dnstypes.Record, err error) {
|
|
var pageNumber = 1
|
|
var size = 100
|
|
|
|
for {
|
|
var req = alidns.CreateDescribeDomainRecordsRequest()
|
|
req.DomainName = domain
|
|
req.PageNumber = requests.NewInteger(pageNumber)
|
|
req.PageSize = requests.NewInteger(size)
|
|
|
|
var resp = alidns.CreateDescribeDomainRecordsResponse()
|
|
err = this.doAPI(req, resp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, record := range resp.DomainRecords.Record {
|
|
// 修正Record
|
|
if record.Type == dnstypes.RecordTypeCNAME && !strings.HasSuffix(record.Value, ".") {
|
|
record.Value += "."
|
|
}
|
|
|
|
records = append(records, &dnstypes.Record{
|
|
Id: record.RecordId,
|
|
Name: record.RR,
|
|
Type: record.Type,
|
|
Value: record.Value,
|
|
Route: record.Line,
|
|
TTL: types.Int32(record.TTL),
|
|
})
|
|
}
|
|
|
|
pageNumber++
|
|
if int64((pageNumber-1)*size) >= resp.TotalCount {
|
|
break
|
|
}
|
|
}
|
|
|
|
// 写入缓存
|
|
if this.ProviderId > 0 {
|
|
sharedDomainRecordsCache.WriteDomainRecords(this.ProviderId, domain, records)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// GetRoutes 读取域名支持的线路数据
|
|
func (this *AliDNSProvider) GetRoutes(domain string) (routes []*dnstypes.Route, err error) {
|
|
var req = alidns.CreateDescribeSupportLinesRequest()
|
|
req.DomainName = domain
|
|
|
|
var resp = alidns.CreateDescribeSupportLinesResponse()
|
|
err = this.doAPI(req, resp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, line := range resp.RecordLines.RecordLine {
|
|
routes = append(routes, &dnstypes.Route{
|
|
Name: line.LineDisplayName,
|
|
Code: line.LineCode,
|
|
})
|
|
}
|
|
return
|
|
}
|
|
|
|
// QueryRecord 查询单个记录
|
|
func (this *AliDNSProvider) QueryRecord(domain string, name string, recordType dnstypes.RecordType) (*dnstypes.Record, error) {
|
|
// 从缓存中读取
|
|
if this.ProviderId > 0 {
|
|
record, hasRecords, _ := sharedDomainRecordsCache.QueryDomainRecord(this.ProviderId, domain, name, recordType)
|
|
if hasRecords { // 有效的搜索
|
|
return record, nil
|
|
}
|
|
}
|
|
|
|
records, err := this.GetRecords(domain)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, record := range records {
|
|
if record.Name == name && record.Type == recordType {
|
|
return record, nil
|
|
}
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
// QueryRecords 查询多个记录
|
|
func (this *AliDNSProvider) QueryRecords(domain string, name string, recordType dnstypes.RecordType) ([]*dnstypes.Record, error) {
|
|
// 从缓存中读取
|
|
if this.ProviderId > 0 {
|
|
records, hasRecords, _ := sharedDomainRecordsCache.QueryDomainRecords(this.ProviderId, domain, name, recordType)
|
|
if hasRecords { // 有效的搜索
|
|
return records, nil
|
|
}
|
|
}
|
|
|
|
records, err := this.GetRecords(domain)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var result = []*dnstypes.Record{}
|
|
for _, record := range records {
|
|
if record.Name == name && record.Type == recordType {
|
|
result = append(result, record)
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// AddRecord 设置记录
|
|
func (this *AliDNSProvider) AddRecord(domain string, newRecord *dnstypes.Record) error {
|
|
var req = alidns.CreateAddDomainRecordRequest()
|
|
req.RR = newRecord.Name
|
|
req.Type = newRecord.Type
|
|
req.Value = newRecord.Value
|
|
req.DomainName = domain
|
|
req.Line = newRecord.Route
|
|
|
|
if newRecord.TTL > 0 {
|
|
req.TTL = requests.NewInteger(types.Int(newRecord.TTL))
|
|
}
|
|
|
|
var resp = alidns.CreateAddDomainRecordResponse()
|
|
err := this.doAPI(req, resp)
|
|
if err != nil {
|
|
return this.WrapError(err, domain, newRecord)
|
|
}
|
|
if resp.IsSuccess() {
|
|
newRecord.Id = resp.RecordId
|
|
|
|
// 加入缓存
|
|
if this.ProviderId > 0 {
|
|
sharedDomainRecordsCache.AddDomainRecord(this.ProviderId, domain, newRecord)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
return this.WrapError(errors.New(resp.GetHttpContentString()), domain, newRecord)
|
|
}
|
|
|
|
// UpdateRecord 修改记录
|
|
func (this *AliDNSProvider) UpdateRecord(domain string, record *dnstypes.Record, newRecord *dnstypes.Record) error {
|
|
var req = alidns.CreateUpdateDomainRecordRequest()
|
|
req.RecordId = record.Id
|
|
req.RR = newRecord.Name
|
|
req.Type = newRecord.Type
|
|
req.Value = newRecord.Value
|
|
req.Line = newRecord.Route
|
|
|
|
if newRecord.TTL > 0 {
|
|
req.TTL = requests.NewInteger(types.Int(newRecord.TTL))
|
|
}
|
|
|
|
var resp = alidns.CreateUpdateDomainRecordResponse()
|
|
err := this.doAPI(req, resp)
|
|
if err != nil {
|
|
return this.WrapError(err, domain, newRecord)
|
|
}
|
|
|
|
newRecord.Id = record.Id
|
|
|
|
// 修改缓存
|
|
if this.ProviderId > 0 {
|
|
sharedDomainRecordsCache.UpdateDomainRecord(this.ProviderId, domain, newRecord)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// DeleteRecord 删除记录
|
|
func (this *AliDNSProvider) DeleteRecord(domain string, record *dnstypes.Record) error {
|
|
var req = alidns.CreateDeleteDomainRecordRequest()
|
|
req.RecordId = record.Id
|
|
|
|
var resp = alidns.CreateDeleteDomainRecordResponse()
|
|
err := this.doAPI(req, resp)
|
|
if err != nil {
|
|
return this.WrapError(err, domain, record)
|
|
}
|
|
|
|
// 删除缓存
|
|
if this.ProviderId > 0 {
|
|
sharedDomainRecordsCache.DeleteDomainRecord(this.ProviderId, domain, record.Id)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// DefaultRoute 默认线路
|
|
func (this *AliDNSProvider) DefaultRoute() string {
|
|
return "default"
|
|
}
|
|
|
|
// 执行请求
|
|
func (this *AliDNSProvider) doAPI(req requests.AcsRequest, resp responses.AcsResponse) error {
|
|
req.SetScheme("https")
|
|
|
|
client, err := alidns.NewClientWithAccessKey(this.regionId, this.accessKeyId, this.accessKeySecret)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = client.DoAction(req, resp)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !resp.IsSuccess() {
|
|
return errors.New(resp.GetHttpContentString())
|
|
}
|
|
return nil
|
|
}
|