mirror of
				https://github.com/TeaOSLab/EdgeAPI.git
				synced 2025-11-04 07:50:25 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			231 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			231 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package dnsclients
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/json"
 | 
						|
	"errors"
 | 
						|
	"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
 | 
						|
	"github.com/TeaOSLab/EdgeAPI/internal/utils/numberutils"
 | 
						|
	"github.com/iwind/TeaGo/maps"
 | 
						|
	"github.com/iwind/TeaGo/types"
 | 
						|
	"io/ioutil"
 | 
						|
	"net/http"
 | 
						|
	"net/url"
 | 
						|
	"strings"
 | 
						|
)
 | 
						|
 | 
						|
// DNSPodProvider DNSPod服务商
 | 
						|
type DNSPodProvider struct {
 | 
						|
	BaseProvider
 | 
						|
 | 
						|
	apiId    string
 | 
						|
	apiToken string
 | 
						|
}
 | 
						|
 | 
						|
// Auth 认证
 | 
						|
func (this *DNSPodProvider) Auth(params maps.Map) error {
 | 
						|
	this.apiId = params.GetString("id")
 | 
						|
	this.apiToken = params.GetString("token")
 | 
						|
 | 
						|
	if len(this.apiId) == 0 {
 | 
						|
		return errors.New("'id' should be not empty")
 | 
						|
	}
 | 
						|
	if len(this.apiToken) == 0 {
 | 
						|
		return errors.New("'token' should not be empty")
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// GetRecords 获取域名列表
 | 
						|
func (this *DNSPodProvider) GetRecords(domain string) (records []*dnstypes.Record, err error) {
 | 
						|
	offset := 0
 | 
						|
	size := 100
 | 
						|
	for {
 | 
						|
		recordsResp, err := this.post("/Record.list", map[string]string{
 | 
						|
			"domain": domain,
 | 
						|
			"offset": numberutils.FormatInt(offset),
 | 
						|
			"length": numberutils.FormatInt(size),
 | 
						|
		})
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
		offset += size
 | 
						|
 | 
						|
		// 记录
 | 
						|
		recordSlice := recordsResp.GetSlice("records")
 | 
						|
		for _, record := range recordSlice {
 | 
						|
			recordMap := maps.NewMap(record)
 | 
						|
			records = append(records, &dnstypes.Record{
 | 
						|
				Id:    recordMap.GetString("id"),
 | 
						|
				Name:  recordMap.GetString("name"),
 | 
						|
				Type:  recordMap.GetString("type"),
 | 
						|
				Value: recordMap.GetString("value"),
 | 
						|
				Route: recordMap.GetString("line"),
 | 
						|
			})
 | 
						|
		}
 | 
						|
 | 
						|
		// 检查是否到头
 | 
						|
		info := recordsResp.GetMap("info")
 | 
						|
		recordTotal := info.GetInt("record_total")
 | 
						|
		if offset >= recordTotal {
 | 
						|
			break
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
// GetRoutes 读取线路数据
 | 
						|
func (this *DNSPodProvider) GetRoutes(domain string) (routes []*dnstypes.Route, err error) {
 | 
						|
	infoResp, err := this.post("/Domain.info", map[string]string{
 | 
						|
		"domain": domain,
 | 
						|
	})
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	domainInfo := infoResp.GetMap("domain")
 | 
						|
	grade := domainInfo.GetString("grade")
 | 
						|
 | 
						|
	linesResp, err := this.post("/Record.Line", map[string]string{
 | 
						|
		"domain":       domain,
 | 
						|
		"domain_grade": grade,
 | 
						|
	})
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	lines := linesResp.GetSlice("lines")
 | 
						|
	if len(lines) == 0 {
 | 
						|
		return nil, nil
 | 
						|
	}
 | 
						|
	for _, line := range lines {
 | 
						|
		lineString := types.String(line)
 | 
						|
		routes = append(routes, &dnstypes.Route{
 | 
						|
			Name: lineString,
 | 
						|
			Code: lineString,
 | 
						|
		})
 | 
						|
	}
 | 
						|
 | 
						|
	return routes, nil
 | 
						|
}
 | 
						|
 | 
						|
// QueryRecord 查询单个记录
 | 
						|
func (this *DNSPodProvider) QueryRecord(domain string, name string, recordType dnstypes.RecordType) (*dnstypes.Record, error) {
 | 
						|
	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, err
 | 
						|
}
 | 
						|
 | 
						|
// AddRecord 设置记录
 | 
						|
func (this *DNSPodProvider) AddRecord(domain string, newRecord *dnstypes.Record) error {
 | 
						|
	if newRecord == nil {
 | 
						|
		return errors.New("invalid new record")
 | 
						|
	}
 | 
						|
 | 
						|
	// 在CHANGE记录后面加入点
 | 
						|
	if newRecord.Type == dnstypes.RecordTypeCNAME && !strings.HasSuffix(newRecord.Value, ".") {
 | 
						|
		newRecord.Value += "."
 | 
						|
	}
 | 
						|
	_, err := this.post("/Record.Create", map[string]string{
 | 
						|
		"domain":      domain,
 | 
						|
		"sub_domain":  newRecord.Name,
 | 
						|
		"record_type": newRecord.Type,
 | 
						|
		"value":       newRecord.Value,
 | 
						|
		"record_line": newRecord.Route,
 | 
						|
	})
 | 
						|
	return err
 | 
						|
}
 | 
						|
 | 
						|
// UpdateRecord 修改记录
 | 
						|
func (this *DNSPodProvider) UpdateRecord(domain string, record *dnstypes.Record, newRecord *dnstypes.Record) error {
 | 
						|
	if record == nil {
 | 
						|
		return errors.New("invalid record")
 | 
						|
	}
 | 
						|
	if newRecord == nil {
 | 
						|
		return errors.New("invalid new record")
 | 
						|
	}
 | 
						|
 | 
						|
	// 在CHANGE记录后面加入点
 | 
						|
	if newRecord.Type == dnstypes.RecordTypeCNAME && !strings.HasSuffix(newRecord.Value, ".") {
 | 
						|
		newRecord.Value += "."
 | 
						|
	}
 | 
						|
	_, err := this.post("/Record.Modify", map[string]string{
 | 
						|
		"domain":      domain,
 | 
						|
		"record_id":   record.Id,
 | 
						|
		"sub_domain":  newRecord.Name,
 | 
						|
		"record_type": newRecord.Type,
 | 
						|
		"value":       newRecord.Value,
 | 
						|
		"record_line": newRecord.Route,
 | 
						|
	})
 | 
						|
	return err
 | 
						|
}
 | 
						|
 | 
						|
// DeleteRecord 删除记录
 | 
						|
func (this *DNSPodProvider) DeleteRecord(domain string, record *dnstypes.Record) error {
 | 
						|
	if record == nil {
 | 
						|
		return errors.New("invalid record to delete")
 | 
						|
	}
 | 
						|
 | 
						|
	_, err := this.post("/Record.Remove", map[string]string{
 | 
						|
		"domain":    domain,
 | 
						|
		"record_id": record.Id,
 | 
						|
	})
 | 
						|
 | 
						|
	return err
 | 
						|
}
 | 
						|
 | 
						|
// 发送请求
 | 
						|
func (this *DNSPodProvider) post(path string, params map[string]string) (maps.Map, error) {
 | 
						|
	apiHost := "https://dnsapi.cn"
 | 
						|
	query := url.Values{
 | 
						|
		"login_token": []string{this.apiId + "," + this.apiToken},
 | 
						|
		"format":      []string{"json"},
 | 
						|
		"lang":        []string{"cn"},
 | 
						|
	}
 | 
						|
	for p, v := range params {
 | 
						|
		query[p] = []string{v}
 | 
						|
	}
 | 
						|
	req, err := http.NewRequest(http.MethodPost, apiHost+path, strings.NewReader(query.Encode()))
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
 | 
						|
	req.Header.Set("User-Agent", "GoEdge Client/1.0.0 (iwind.liu@gmail.com)")
 | 
						|
 | 
						|
	client := http.Client{}
 | 
						|
	resp, err := client.Do(req)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	defer func() {
 | 
						|
		_ = resp.Body.Close()
 | 
						|
		client.CloseIdleConnections()
 | 
						|
	}()
 | 
						|
	body, err := ioutil.ReadAll(resp.Body)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	m := maps.Map{}
 | 
						|
	err = json.Unmarshal(body, &m)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	status := m.GetMap("status")
 | 
						|
	code := status.GetString("code")
 | 
						|
	if code != "1" {
 | 
						|
		return nil, errors.New("code: " + code + ", message: " + status.GetString("message"))
 | 
						|
	}
 | 
						|
 | 
						|
	return m, nil
 | 
						|
}
 | 
						|
 | 
						|
// DefaultRoute 默认线路
 | 
						|
func (this *DNSPodProvider) DefaultRoute() string {
 | 
						|
	return "默认"
 | 
						|
}
 |