Skip to content

Commit

Permalink
Merge pull request #17 from crhstack/main
Browse files Browse the repository at this point in the history
add cloudflare
  • Loading branch information
eryajf authored Sep 11, 2024
2 parents 475522e + b32064d commit c13d3cb
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 8 deletions.
7 changes: 6 additions & 1 deletion config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,9 @@ cloud_providers:
- name: d1
secretId: "xxxxx"
secretKey: "xxxxx"
# 目前支持Tencent, Aliyun, Godaddy,DNALA, Amazon,如需支持更多云厂商,请提交 issue,也欢迎 PR
cloudflare:
accounts:
- name: a1
secretId: "xxxxx" # 注册邮箱
secretKey: "xxxxx" # ApiKey密钥
# 目前支持Tencent, Aliyun, Godaddy, DNALA, Amazon, CloudFlare,如需支持更多云厂商,请提交 issue,也欢迎 PR
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/route53 v1.43.2
github.com/aws/aws-sdk-go-v2/service/route53domains v1.25.6
github.com/charmbracelet/log v0.2.2
github.com/cloudflare/cloudflare-go v0.103.0
github.com/go-resty/resty/v2 v2.14.0
github.com/golang-module/carbon/v2 v2.3.12
github.com/google/uuid v1.6.0
Expand All @@ -39,12 +40,16 @@ require (
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17 // indirect
github.com/aws/smithy-go v1.20.4 // indirect
github.com/clbanning/mxj/v2 v2.5.5 // indirect
github.com/goccy/go-json v0.10.3 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/rogpeppe/go-internal v1.12.1-0.20240709150035-ccf4b4329d21 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tjfoc/gmsm v1.3.2 // indirect
golang.org/x/text v0.17.0 // indirect
golang.org/x/time v0.6.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)

Expand Down
211 changes: 210 additions & 1 deletion pkg/provider/cloudflare.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,212 @@
package provider

// TODO: 待实现
import (
"context"
"encoding/json"
"fmt"
"github.com/alibabacloud-go/tea/tea"
"github.com/cloudflare/cloudflare-go"
"github.com/eryajf/cloud_dns_exporter/public"
"github.com/golang-module/carbon/v2"
"sync"
"time"
)

type CloudFlareDNS struct {
account public.Account
client *cloudflare.API

Check failure on line 17 in pkg/provider/cloudflare.go

View workflow job for this annotation

GitHub Actions / golint

undefined: cloudflare (typecheck)
}

type Header struct {
XAuthEmail interface{} `json:"X-Auth-Email"`
XAuthKey interface{} `json:"X-Auth-Key"`
ContentType string `json:"Content-Type"`
}

func NewCloudflareDNSClient(token string, email string) (*cloudflare.API, error) {

Check failure on line 26 in pkg/provider/cloudflare.go

View workflow job for this annotation

GitHub Actions / golint

undefined: cloudflare (typecheck)
return cloudflare.New(token, email)
}

func NewCloudFlareDNS(account public.Account) *CloudFlareDNS {
client, _ := NewCloudflareDNSClient(account.SecretKey, account.SecretID)
return &CloudFlareDNS{
account: account,
client: client,
}
}

func (cf *CloudFlareDNS) ListDomains() ([]Domain, error) {
cfd := NewCloudFlareDNS(public.Account{
CloudProvider: cf.account.CloudProvider,
CloudName: cf.account.CloudName,
SecretID: cf.account.SecretID,
SecretKey: cf.account.SecretKey,
})
cf.client = cfd.client
var (
dataObj []Domain
wg sync.WaitGroup
mu sync.Mutex
)
domains, err := cf.getDomainList()
if err != nil {
return nil, err
}
ticker := time.NewTicker(100 * time.Millisecond)
for _, domain := range domains {
wg.Add(1)
go func(domain cloudflare.Zone) {
defer wg.Done()
<-ticker.C
domainCreateAndExpiryDate, _ := cf.getDomainCreateAndExpiryDate(domain)
mu.Lock()
dataObj = append(dataObj, Domain{
CloudName: domain.Name,
CloudProvider: cf.account.CloudProvider,
CreatedDate: domainCreateAndExpiryDate.CreatedDate,
DaysUntilExpiry: domainCreateAndExpiryDate.DaysUntilExpiry,
DomainID: domain.ID,
DomainName: domain.Name,
DomainRemark: tea.StringValue(nil),
DomainStatus: domain.Status,
ExpiryDate: domainCreateAndExpiryDate.ExpiryDate,
})
mu.Unlock()
}(domain)
}
wg.Wait()
return dataObj, err
}

func (cf *CloudFlareDNS) ListRecords() ([]Record, error) {
var (
dataObj []Record
domains []Domain
wg sync.WaitGroup
mu sync.Mutex
)
cfd := NewCloudFlareDNS(public.Account{
CloudProvider: cf.account.CloudProvider,
CloudName: cf.account.CloudName,
SecretID: cf.account.SecretID,
SecretKey: cf.account.SecretKey,
})
cf.client = cfd.client
rst, err := public.Cache.Get(public.DomainList + "_" + cf.account.CloudProvider + "_" + cf.account.CloudName)
if err != nil {
return nil, err
}
err = json.Unmarshal(rst, &domains)
if err != nil {
return nil, err
}
results := make(map[string][]cloudflare.DNSRecord)
ticker := time.NewTicker(100 * time.Millisecond)
for _, domain := range domains {
wg.Add(1)
go func(domain Domain) {
defer wg.Done()
<-ticker.C
records, err := cf.getRecordList(domain.DomainName)
if err != nil {
fmt.Printf("cloudflare get record list error: %v", err)
return
}
mu.Lock()
results[domain.DomainName] = records
mu.Unlock()
}(domain)
}
wg.Wait()
for domain, records := range results {
for _, record := range records {
dataObj = append(dataObj, Record{
CloudName: cf.account.CloudName,
CloudProvider: cf.account.CloudProvider,
DomainName: domain,
RecordID: record.ID,
RecordName: record.Name,
RecordType: record.Type,
RecordRemark: tea.StringValue(nil),
RecordStatus: "enable",
RecordTTL: fmt.Sprintf("%d", record.TTL),
FullRecord: record.Name,
})
}
}
return dataObj, err
}

// getDomainList 获取解析域域名列表
func (cf *CloudFlareDNS) getDomainList() (rst []cloudflare.Zone, err error) {

Check failure on line 141 in pkg/provider/cloudflare.go

View workflow job for this annotation

GitHub Actions / golint

undefined: cloudflare (typecheck)
client, err := NewCloudflareDNSClient(cf.account.SecretKey, cf.account.SecretID)
if err != nil {
fmt.Printf("cloudflare client init error: %v", err)
return
}
zones, err := client.ListZones(context.Background())
if err != nil {
fmt.Printf("cloudflare list zones error: %v", err)
return
}
for _, zone := range zones {
rst = append(rst, zone)
}
return
}

func (cf *CloudFlareDNS) getAccountId() (account cloudflare.Account, err error) {
client, _ := NewCloudflareDNSClient(cf.account.SecretKey, cf.account.SecretID)
accounts, _, err := client.Accounts(context.Background(), cloudflare.AccountsListParams{})
if err != nil {
return
}
for _, a := range accounts {
account = a
}
return
}

func (cf *CloudFlareDNS) getRecordList(domain string) (rst []cloudflare.DNSRecord, err error) {
page := 1
pageSize := 2
client, _ := NewCloudflareDNSClient(cf.account.SecretKey, cf.account.SecretID)
zoneID, err := client.ZoneIDByName(domain)
if err != nil {
return
}
for {
records, r, err := client.ListDNSRecords(context.Background(), cloudflare.ZoneIdentifier(zoneID), cloudflare.ListDNSRecordsParams{
ResultInfo: cloudflare.ResultInfo{Page: page, PerPage: pageSize},
})
if err != nil {
return nil, err
}
for _, record := range records {
rst = append(rst, record)
}
if page*pageSize > r.Total {
break
}
page++
}
return
}

func (cf *CloudFlareDNS) getDomainCreateAndExpiryDate(domain cloudflare.Zone) (d Domain, err error) {
client, err := NewCloudflareDNSClient(cf.account.SecretKey, cf.account.SecretID)
if err != nil {
return
}
account, err := cf.getAccountId()
if err != nil {
return
}
domainInfo, err := client.RegistrarDomain(context.Background(), account.ID, domain.Name)
d.CreatedDate = domainInfo.CreatedAt.String()
d.ExpiryDate = domainInfo.ExpiresAt.String()
if d.ExpiryDate != "" {
d.DaysUntilExpiry = carbon.Now().DiffInDays(carbon.Parse(d.ExpiryDate))
}
return
}
10 changes: 10 additions & 0 deletions pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ func init() {
},
}
})
Factory.Register(public.CloudFlareDnsProvider, func(account map[string]string) DNSProvider {
return &CloudFlareDNS{
account: public.Account{
CloudProvider: public.CloudFlareDnsProvider,
CloudName: account["name"],
SecretID: account["secretId"],
SecretKey: account["secretKey"],
},
}
})
}

// Doamin 域名信息
Expand Down
13 changes: 7 additions & 6 deletions public/public.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ func InitSvc() {

const (
// Cloud Providers
TencentDnsProvider string = "tencent"
AliyunDnsProvider string = "aliyun"
GodaddyDnsProvider string = "godaddy"
DNSLaDnsProvider string = "dnsla"
HuaweiDnsProvider string = "huawei"
AmazonDnsProvider string = "amazon"
TencentDnsProvider string = "tencent"
AliyunDnsProvider string = "aliyun"
GodaddyDnsProvider string = "godaddy"
DNSLaDnsProvider string = "dnsla"
HuaweiDnsProvider string = "huawei"
AmazonDnsProvider string = "amazon"
CloudFlareDnsProvider string = "cloudflare"
// Metrics Name
DomainList string = "domain_list"
RecordList string = "record_list"
Expand Down

0 comments on commit c13d3cb

Please sign in to comment.