mirror of
https://github.com/TeaOSLab/EdgeAPI.git
synced 2025-11-06 01:50:25 +08:00
域名解析增加EdgeDNS API
This commit is contained in:
441
internal/dnsclients/provider_edge_dns_api.go
Normal file
441
internal/dnsclients/provider_edge_dns_api.go
Normal file
@@ -0,0 +1,441 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package dnsclients
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/tls"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/edgeapi"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var edgeDNSHTTPClient = &http.Client{
|
||||||
|
Timeout: 10 * time.Second,
|
||||||
|
Transport: &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
type EdgeDNSAPIProvider struct {
|
||||||
|
host string
|
||||||
|
accessKeyId string
|
||||||
|
accessKeySecret string
|
||||||
|
|
||||||
|
role string // admin | user
|
||||||
|
accessToken string
|
||||||
|
accessTokenExpiresAt int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auth 认证
|
||||||
|
func (this *EdgeDNSAPIProvider) Auth(params maps.Map) error {
|
||||||
|
this.role = params.GetString("role")
|
||||||
|
this.host = params.GetString("host")
|
||||||
|
this.accessKeyId = params.GetString("accessKeyId")
|
||||||
|
this.accessKeySecret = params.GetString("accessKeySecret")
|
||||||
|
|
||||||
|
if len(this.role) == 0 {
|
||||||
|
this.role = "user"
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(this.host) == 0 {
|
||||||
|
return errors.New("'host' should not be empty")
|
||||||
|
}
|
||||||
|
if !regexp.MustCompile(`^(?i)(http|https):`).MatchString(this.host) {
|
||||||
|
this.host = "http://" + this.host
|
||||||
|
}
|
||||||
|
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDomains 获取所有域名列表
|
||||||
|
func (this *EdgeDNSAPIProvider) GetDomains() (domains []string, err error) {
|
||||||
|
var offset = 0
|
||||||
|
var size = 100
|
||||||
|
for {
|
||||||
|
var resp = &edgeapi.ListNSDomainsResponse{}
|
||||||
|
err = this.doAPI("/NSDomainService/ListNSDomains", map[string]any{
|
||||||
|
"offset": offset,
|
||||||
|
"size": size,
|
||||||
|
}, resp)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, domain := range resp.Data.NSDomains {
|
||||||
|
domains = append(domains, domain.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(resp.Data.NSDomains) < size {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += size
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRecords 获取域名解析记录列表
|
||||||
|
func (this *EdgeDNSAPIProvider) GetRecords(domain string) (records []*dnstypes.Record, err error) {
|
||||||
|
var domainResp = &edgeapi.FindDomainWithNameResponse{}
|
||||||
|
err = this.doAPI("/NSDomainService/FindNSDomainWithName", map[string]any{
|
||||||
|
"name": domain,
|
||||||
|
}, domainResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var domainId = domainResp.Data.NSDomain.Id
|
||||||
|
if domainId == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var offset = 0
|
||||||
|
var size = 100
|
||||||
|
for {
|
||||||
|
var recordsResp = &edgeapi.ListNSRecordsResponse{}
|
||||||
|
err = this.doAPI("/NSRecordService/ListNSRecords", map[string]any{
|
||||||
|
"nsDomainId": domainId,
|
||||||
|
"offset": offset,
|
||||||
|
"size": size,
|
||||||
|
}, recordsResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var nsRecords = recordsResp.Data.NSRecords
|
||||||
|
for _, record := range nsRecords {
|
||||||
|
var routeCode = this.DefaultRoute()
|
||||||
|
if len(record.NSRoutes) > 0 {
|
||||||
|
routeCode = record.NSRoutes[0].Code
|
||||||
|
}
|
||||||
|
|
||||||
|
records = append(records, &dnstypes.Record{
|
||||||
|
Id: types.String(record.Id),
|
||||||
|
Name: record.Name,
|
||||||
|
Type: record.Type,
|
||||||
|
Value: record.Value,
|
||||||
|
Route: routeCode,
|
||||||
|
TTL: record.TTL,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(nsRecords) < size {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += size
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRoutes 读取域名支持的线路数据
|
||||||
|
func (this *EdgeDNSAPIProvider) GetRoutes(domain string) (routes []*dnstypes.Route, err error) {
|
||||||
|
// default
|
||||||
|
routes = append(routes, &dnstypes.Route{
|
||||||
|
Name: "默认线路",
|
||||||
|
Code: this.DefaultRoute(),
|
||||||
|
})
|
||||||
|
|
||||||
|
// 世界区域
|
||||||
|
{
|
||||||
|
var routesResp = &edgeapi.FindAllNSRoutesResponse{}
|
||||||
|
err = this.doAPI("/NSRouteService/FindAllDefaultWorldRegionRoutes", map[string]any{}, routesResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, route := range routesResp.Data.NSRoutes {
|
||||||
|
routes = append(routes, &dnstypes.Route{
|
||||||
|
Name: route.Name,
|
||||||
|
Code: route.Code,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 中国省份
|
||||||
|
{
|
||||||
|
var routesResp = &edgeapi.FindAllNSRoutesResponse{}
|
||||||
|
err = this.doAPI("/NSRouteService/FindAllDefaultChinaProvinceRoutes", map[string]any{}, routesResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, route := range routesResp.Data.NSRoutes {
|
||||||
|
routes = append(routes, &dnstypes.Route{
|
||||||
|
Name: route.Name,
|
||||||
|
Code: route.Code,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ISP
|
||||||
|
{
|
||||||
|
var routesResp = &edgeapi.FindAllNSRoutesResponse{}
|
||||||
|
err = this.doAPI("/NSRouteService/FindAllDefaultISPRoutes", map[string]any{}, routesResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, route := range routesResp.Data.NSRoutes {
|
||||||
|
routes = append(routes, &dnstypes.Route{
|
||||||
|
Name: route.Name,
|
||||||
|
Code: route.Code,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自定义
|
||||||
|
{
|
||||||
|
var routesResp = &edgeapi.FindAllNSRoutesResponse{}
|
||||||
|
err = this.doAPI("/NSRouteService/FindAllNSRoutes", map[string]any{}, routesResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, route := range routesResp.Data.NSRoutes {
|
||||||
|
routes = append(routes, &dnstypes.Route{
|
||||||
|
Name: route.Name,
|
||||||
|
Code: route.Code,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryRecord 查询单个记录
|
||||||
|
func (this *EdgeDNSAPIProvider) QueryRecord(domain string, name string, recordType dnstypes.RecordType) (*dnstypes.Record, error) {
|
||||||
|
var domainResp = &edgeapi.FindDomainWithNameResponse{}
|
||||||
|
err := this.doAPI("/NSDomainService/FindNSDomainWithName", map[string]any{
|
||||||
|
"name": domain,
|
||||||
|
}, domainResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var domainId = domainResp.Data.NSDomain.Id
|
||||||
|
if domainId == 0 {
|
||||||
|
return nil, errors.New("can not find domain '" + domain + "'")
|
||||||
|
}
|
||||||
|
|
||||||
|
var recordResp = &edgeapi.FindNSRecordWithNameAndTypeResponse{}
|
||||||
|
err = this.doAPI("/NSRecordService/FindNSRecordWithNameAndType", map[string]any{
|
||||||
|
"nsDomainId": domainId,
|
||||||
|
"name": name,
|
||||||
|
"type": recordType,
|
||||||
|
}, recordResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var record = recordResp.Data.NSRecord
|
||||||
|
if record.Id <= 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var routeCode = this.DefaultRoute()
|
||||||
|
if len(record.NSRoutes) > 0 {
|
||||||
|
routeCode = record.NSRoutes[0].Code
|
||||||
|
}
|
||||||
|
|
||||||
|
return &dnstypes.Record{
|
||||||
|
Id: types.String(record.Id),
|
||||||
|
Name: record.Name,
|
||||||
|
Type: record.Type,
|
||||||
|
Value: record.Value,
|
||||||
|
Route: routeCode,
|
||||||
|
TTL: record.TTL,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddRecord 设置记录
|
||||||
|
func (this *EdgeDNSAPIProvider) AddRecord(domain string, newRecord *dnstypes.Record) error {
|
||||||
|
var domainResp = &edgeapi.FindDomainWithNameResponse{}
|
||||||
|
err := this.doAPI("/NSDomainService/FindNSDomainWithName", map[string]any{
|
||||||
|
"name": domain,
|
||||||
|
}, domainResp)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var domainId = domainResp.Data.NSDomain.Id
|
||||||
|
if domainId == 0 {
|
||||||
|
return errors.New("can not find domain '" + domain + "'")
|
||||||
|
}
|
||||||
|
|
||||||
|
if newRecord.Type == dnstypes.RecordTypeCNAME && !strings.HasSuffix(newRecord.Value, ".") {
|
||||||
|
newRecord.Value += "."
|
||||||
|
}
|
||||||
|
|
||||||
|
var createResp = &edgeapi.CreateNSRecordResponse{}
|
||||||
|
var routes = []string{}
|
||||||
|
if len(newRecord.Route) > 0 {
|
||||||
|
routes = []string{newRecord.Route}
|
||||||
|
}
|
||||||
|
err = this.doAPI("/NSRecordService/CreateNSRecord", map[string]any{
|
||||||
|
"nsDomainId": domainId,
|
||||||
|
"name": newRecord.Name,
|
||||||
|
"type": strings.ToUpper(newRecord.Type),
|
||||||
|
"value": newRecord.Value,
|
||||||
|
"ttl": newRecord.TTL,
|
||||||
|
"nsRouteCodes": routes,
|
||||||
|
}, createResp)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
newRecord.Id = types.String(createResp.Data.NSRecordId)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateRecord 修改记录
|
||||||
|
func (this *EdgeDNSAPIProvider) UpdateRecord(domain string, record *dnstypes.Record, newRecord *dnstypes.Record) error {
|
||||||
|
if newRecord.Type == dnstypes.RecordTypeCNAME && !strings.HasSuffix(newRecord.Value, ".") {
|
||||||
|
newRecord.Value += "."
|
||||||
|
}
|
||||||
|
|
||||||
|
var createResp = &edgeapi.UpdateNSRecordResponse{}
|
||||||
|
var routes = []string{}
|
||||||
|
if len(newRecord.Route) > 0 {
|
||||||
|
routes = []string{newRecord.Route}
|
||||||
|
}
|
||||||
|
err := this.doAPI("/NSRecordService/UpdateNSRecord", map[string]any{
|
||||||
|
"nsRecordId": types.Int64(record.Id),
|
||||||
|
"name": newRecord.Name,
|
||||||
|
"type": strings.ToUpper(newRecord.Type),
|
||||||
|
"value": newRecord.Value,
|
||||||
|
"ttl": newRecord.TTL,
|
||||||
|
"nsRouteCodes": routes,
|
||||||
|
"isOn": true, // important
|
||||||
|
}, createResp)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteRecord 删除记录
|
||||||
|
func (this *EdgeDNSAPIProvider) DeleteRecord(domain string, record *dnstypes.Record) error {
|
||||||
|
var resp = &edgeapi.SuccessResponse{}
|
||||||
|
err := this.doAPI("/NSRecordService/DeleteNSRecord", map[string]any{
|
||||||
|
"nsRecordId": types.Int64(record.Id),
|
||||||
|
}, resp)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultRoute 默认线路
|
||||||
|
func (this *EdgeDNSAPIProvider) DefaultRoute() string {
|
||||||
|
return "default"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *EdgeDNSAPIProvider) doAPI(path string, params map[string]any, respPtr edgeapi.ResponseInterface) error {
|
||||||
|
accessToken, err := this.getToken()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
paramsJSON, err := json.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req, err := http.NewRequest(http.MethodPost, this.host+path, bytes.NewReader(paramsJSON))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req.Header.Set("User-Agent", teaconst.ProductName+"/"+teaconst.Version)
|
||||||
|
req.Header.Set("X-Edge-Access-Token", accessToken)
|
||||||
|
|
||||||
|
resp, err := edgeDNSHTTPClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return errors.New("invalid response status code '" + types.String(resp.StatusCode) + "'")
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(data, respPtr)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("decode response failed: " + err.Error() + ", JSON: " + string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !respPtr.IsValid() {
|
||||||
|
return respPtr.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *EdgeDNSAPIProvider) getToken() (string, error) {
|
||||||
|
if len(this.accessToken) > 0 && this.accessTokenExpiresAt > time.Now().Unix()+600 /** 600秒是防止当前服务器和API服务器之间有时间差 **/ {
|
||||||
|
return this.accessToken, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var params = maps.Map{
|
||||||
|
"type": this.role,
|
||||||
|
"accessKeyId": this.accessKeyId,
|
||||||
|
"accessKey": this.accessKeySecret,
|
||||||
|
}
|
||||||
|
paramsJSON, err := json.Marshal(params)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
req, err := http.NewRequest(http.MethodPost, this.host+"/APIAccessTokenService/getAPIAccessToken", bytes.NewReader(paramsJSON))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
req.Header.Set("User-Agent", teaconst.ProductName+"/"+teaconst.Version)
|
||||||
|
resp, err := edgeDNSHTTPClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
_ = resp.Body.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return "", errors.New("invalid response code '" + types.String(resp.StatusCode) + "'")
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tokenResp = &edgeapi.GetAPIAccessToken{}
|
||||||
|
err = json.Unmarshal(data, tokenResp)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if tokenResp.Code != 200 {
|
||||||
|
return "", errors.New("invalid code '" + types.String(tokenResp.Code) + "', message: " + tokenResp.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.accessToken = tokenResp.Data.Token
|
||||||
|
this.accessTokenExpiresAt = tokenResp.Data.ExpiresAt
|
||||||
|
return this.accessToken, nil
|
||||||
|
}
|
||||||
163
internal/dnsclients/provider_edge_dns_api_test.go
Normal file
163
internal/dnsclients/provider_edge_dns_api_test.go
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package dnsclients_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
|
||||||
|
"github.com/iwind/TeaGo/logs"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
const edgeDNSAPIDomainName = "hello2.com"
|
||||||
|
|
||||||
|
func TestEdgeDNSAPIProvider_GetDomains(t *testing.T) {
|
||||||
|
provider, err := testEdgeDNSAPIProvider()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
domains, err := provider.GetDomains()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("domains:", domains)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEdgeDNSAPIProvider_GetRecords(t *testing.T) {
|
||||||
|
provider, err := testEdgeDNSAPIProvider()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
records, err := provider.GetRecords(edgeDNSAPIDomainName)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
logs.PrintAsJSON(records, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEdgeDNSAPIProvider_GetRoutes(t *testing.T) {
|
||||||
|
provider, err := testEdgeDNSAPIProvider()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
routes, err := provider.GetRoutes(edgeDNSAPIDomainName)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
logs.PrintAsJSON(routes, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEdgeDNSAPIProvider_QueryRecord(t *testing.T) {
|
||||||
|
provider, err := testEdgeDNSAPIProvider()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
record, err := provider.QueryRecord(edgeDNSAPIDomainName, "cdn", dnstypes.RecordTypeA)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
logs.PrintAsJSON(record)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEdgeDNSAPIProvider_AddRecord(t *testing.T) {
|
||||||
|
provider, err := testEdgeDNSAPIProvider()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
err = provider.AddRecord(edgeDNSAPIDomainName, &dnstypes.Record{
|
||||||
|
Id: "",
|
||||||
|
Name: "example",
|
||||||
|
Type: dnstypes.RecordTypeA,
|
||||||
|
Value: "10.0.0.1",
|
||||||
|
Route: "china:province:beijing",
|
||||||
|
TTL: 300,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("ok")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEdgeDNSAPIProvider_UpdateRecord(t *testing.T) {
|
||||||
|
provider, err := testEdgeDNSAPIProvider()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
record, err := provider.QueryRecord(edgeDNSAPIDomainName, "cdn", dnstypes.RecordTypeA)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if record == nil {
|
||||||
|
t.Log("not found record")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//record.Id = ""
|
||||||
|
err = provider.UpdateRecord(edgeDNSAPIDomainName, record, &dnstypes.Record{
|
||||||
|
Id: "",
|
||||||
|
Name: record.Name,
|
||||||
|
Type: record.Type,
|
||||||
|
Value: "127.0.0.3",
|
||||||
|
Route: record.Route,
|
||||||
|
TTL: 30,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("ok")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEdgeDNSAPIProvider_DeleteRecord(t *testing.T) {
|
||||||
|
provider, err := testEdgeDNSAPIProvider()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
record, err := provider.QueryRecord(edgeDNSAPIDomainName, "example", "A")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if record == nil {
|
||||||
|
t.Log("not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = provider.DeleteRecord(edgeDNSAPIDomainName, &dnstypes.Record{
|
||||||
|
Id: record.Id,
|
||||||
|
Name: "example",
|
||||||
|
Type: "A",
|
||||||
|
Value: "",
|
||||||
|
Route: "",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("ok")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEdgeDNSAPIProvider_DefaultRoute(t *testing.T) {
|
||||||
|
provider, err := testEdgeDNSAPIProvider()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Log(provider.DefaultRoute())
|
||||||
|
}
|
||||||
|
|
||||||
|
func testEdgeDNSAPIProvider() (dnsclients.ProviderInterface, error) {
|
||||||
|
provider := &dnsclients.EdgeDNSAPIProvider{}
|
||||||
|
err := provider.Auth(maps.Map{
|
||||||
|
"role": "user",
|
||||||
|
"host": "http://127.0.0.1:8004",
|
||||||
|
"accessKeyId": "JOvsyXIFqkQbh5kl",
|
||||||
|
"accessKeySecret": "t0RY8YO3R58VbJJNp0RqKw9KWNpObwtE",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return provider, nil
|
||||||
|
}
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
|
||||||
|
|
||||||
package dnsclients
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
|
|
||||||
"github.com/iwind/TeaGo/maps"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UserEdgeDNSProvider struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auth 认证
|
|
||||||
func (this *UserEdgeDNSProvider) Auth(params maps.Map) error {
|
|
||||||
// TODO
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetDomains 获取所有域名列表
|
|
||||||
func (this *UserEdgeDNSProvider) GetDomains() (domains []string, err error) {
|
|
||||||
// TODO
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetRecords 获取域名解析记录列表
|
|
||||||
func (this *UserEdgeDNSProvider) GetRecords(domain string) (records []*dnstypes.Record, err error) {
|
|
||||||
// TODO
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetRoutes 读取域名支持的线路数据
|
|
||||||
func (this *UserEdgeDNSProvider) GetRoutes(domain string) (routes []*dnstypes.Route, err error) {
|
|
||||||
// TODO
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// QueryRecord 查询单个记录
|
|
||||||
func (this *UserEdgeDNSProvider) QueryRecord(domain string, name string, recordType dnstypes.RecordType) (*dnstypes.Record, error) {
|
|
||||||
// TODO
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddRecord 设置记录
|
|
||||||
func (this *UserEdgeDNSProvider) AddRecord(domain string, newRecord *dnstypes.Record) error {
|
|
||||||
// TODO
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateRecord 修改记录
|
|
||||||
func (this *UserEdgeDNSProvider) UpdateRecord(domain string, record *dnstypes.Record, newRecord *dnstypes.Record) error {
|
|
||||||
// TODO
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteRecord 删除记录
|
|
||||||
func (this *UserEdgeDNSProvider) DeleteRecord(domain string, record *dnstypes.Record) error {
|
|
||||||
// TODO
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultRoute 默认线路
|
|
||||||
func (this *UserEdgeDNSProvider) DefaultRoute() string {
|
|
||||||
// TODO
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
@@ -13,13 +13,13 @@ const (
|
|||||||
ProviderTypeHuaweiDNS ProviderType = "huaweiDNS" // 华为DNS
|
ProviderTypeHuaweiDNS ProviderType = "huaweiDNS" // 华为DNS
|
||||||
ProviderTypeCloudFlare ProviderType = "cloudFlare" // CloudFlare DNS
|
ProviderTypeCloudFlare ProviderType = "cloudFlare" // CloudFlare DNS
|
||||||
ProviderTypeLocalEdgeDNS ProviderType = "localEdgeDNS" // 和当前系统集成的EdgeDNS
|
ProviderTypeLocalEdgeDNS ProviderType = "localEdgeDNS" // 和当前系统集成的EdgeDNS
|
||||||
ProviderTypeUserEdgeDNS ProviderType = "userEdgeDNS" // 通过API连接的EdgeDNS
|
ProviderTypeEdgeDNSAPI ProviderType = "edgeDNSAPI" // 通过API连接的EdgeDNS
|
||||||
ProviderTypeCustomHTTP ProviderType = "customHTTP" // 自定义HTTP接口
|
ProviderTypeCustomHTTP ProviderType = "customHTTP" // 自定义HTTP接口
|
||||||
)
|
)
|
||||||
|
|
||||||
// FindAllProviderTypes 所有的服务商类型
|
// FindAllProviderTypes 所有的服务商类型
|
||||||
func FindAllProviderTypes() []maps.Map {
|
func FindAllProviderTypes() []maps.Map {
|
||||||
typeMaps := []maps.Map{
|
var typeMaps = []maps.Map{
|
||||||
{
|
{
|
||||||
"name": "阿里云DNS",
|
"name": "阿里云DNS",
|
||||||
"code": ProviderTypeAliDNS,
|
"code": ProviderTypeAliDNS,
|
||||||
@@ -40,6 +40,11 @@ func FindAllProviderTypes() []maps.Map {
|
|||||||
"code": ProviderTypeCloudFlare,
|
"code": ProviderTypeCloudFlare,
|
||||||
"description": "CloudFlare提供的DNS服务。",
|
"description": "CloudFlare提供的DNS服务。",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "EdgeDNS API",
|
||||||
|
"code": ProviderTypeEdgeDNSAPI,
|
||||||
|
"description": "通过API连接GoEdge商业版系统提供的DNS服务。",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
typeMaps = filterTypeMaps(typeMaps)
|
typeMaps = filterTypeMaps(typeMaps)
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ func FindProvider(providerType ProviderType) ProviderInterface {
|
|||||||
return &CloudFlareProvider{}
|
return &CloudFlareProvider{}
|
||||||
case ProviderTypeCustomHTTP:
|
case ProviderTypeCustomHTTP:
|
||||||
return &CustomHTTPProvider{}
|
return &CustomHTTPProvider{}
|
||||||
|
case ProviderTypeUserEdgeDNS:
|
||||||
|
return &EdgeDNSAPIProvider{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
Reference in New Issue
Block a user