Skip to content

Commit 21c317d

Browse files
authored
Merge pull request #5 from eryajf/feat_godaddy
add godaddy
2 parents d5b45bb + c00abe6 commit 21c317d

File tree

8 files changed

+195
-6
lines changed

8 files changed

+195
-6
lines changed

.github/workflows/buildAndPush-binary-to-release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ jobs:
2727
overwrite: true
2828
build_command: "make"
2929
build_flags: "build VERSION=${{ env.GITHUB_REF_NAME }}"
30+
executable_compression: "upx -9"
3031
goversion: 1.22 # 可以指定编译使用的 Golang 版本
3132
binary_name: "cloud_dns_exporter" # 可以指定二进制文件的名称
3233
extra_files: config.example.yaml LICENSE README.md # 需要包含的额外文件

README.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@
2424

2525
这个项目,希望能够让你轻松掌握到每个域名解析的证书信息,从而在更换证书时,不会遗漏任何一个解析。
2626

27-
支持多种DNS提供商(目前支持阿里云,腾讯云,其他更多,期待有缘人PR),且支持单提供商多账号管理。
27+
支持多种 DNS 提供商(目前支持阿里云,腾讯云,其他更多,期待有缘人PR),且支持单提供商多账号管理。
2828

2929
## 如何使用
3030

3131
可以直接在 [Release](https://github.com/eryajf/cloud_dns_exporter/releases) 发布页面下载二进制,然后更改配置文件,直接运行即可。
3232

33-
默认端口监听在`21798`,为什么选择这个端口,因为项目对应在grafana中的仪表板ID就是[21798](https://grafana.com/grafana/dashboards/21798-cloud-dns-record-info/)
33+
默认端口监听在 `21798`,为什么选择这个端口,因为项目对应在 Grafana 中的仪表板ID就是 [21798](https://grafana.com/grafana/dashboards/21798-cloud-dns-record-info/)
3434

35-
你也可以选择使用docker部署,部署时把config.yaml在本地配置好,然后运行时,通过挂载(`-v ./config.yaml:/app/config.yaml`)覆盖容器内默认配置即可。
35+
你也可以选择使用 Docker 部署,部署时把 `config.yaml` 在本地配置好,然后运行时,通过挂载(`-v ./config.yaml:/app/config.yaml`)覆盖容器内默认配置即可。
3636

3737
镜像地址:
3838
- 国外: `eryajf/cloud_dns_exporter`
@@ -108,13 +108,19 @@ record_cert_info{
108108
error_msg="错误信息"} 30 (此value为记录的证书距离到期的天数)
109109
```
110110

111+
## 已支持 DNS 服务商
112+
113+
- [x] Tencent DnsPod
114+
- [x] Aliyun Dns
115+
- [x] Godaddy
116+
111117
## Grafana 仪表板
112118

113119
项目对应的 Grafana Dashboard ID: [21798](https://grafana.com/grafana/dashboards/21798-cloud-dns-record-info/)
114120

115121
概览与域名列表:
116122

117-
![](https://t.eryajf.net/imgs/2024/08/1725118602116.webp)
123+
![](https://t.eryajf.net/imgs/2024/09/1725288099522.webp)
118124

119125
解析记录与证书详情列表:
120126

config.example.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,9 @@ cloud_providers:
1515
- name: a1
1616
secretId: "xxxxx"
1717
secretKey: "xxxxx"
18-
# 目前仅支持腾讯云和阿里云,如需支持更多云厂商,请提交 issue,也欢迎 PR
18+
godaddy:
19+
accounts:
20+
- name: g1
21+
secretId: "xxxxx"
22+
secretKey: "xxxxx"
23+
# 目前支持Tencent, Aliyun, Godaddy,如需支持更多云厂商,请提交 issue,也欢迎 PR

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ require (
1010
github.com/alibabacloud-go/domain-20180129/v4 v4.2.0
1111
github.com/alibabacloud-go/tea v1.2.2
1212
github.com/allegro/bigcache/v3 v3.1.0
13+
github.com/alyx/go-daddy v0.0.0-20240819232932-c2e4d209da9b
1314
github.com/charmbracelet/log v0.2.2
1415
github.com/golang-module/carbon/v2 v2.3.12
1516
github.com/prometheus/client_golang v1.16.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ github.com/aliyun/credentials-go v1.3.1 h1:uq/0v7kWrxmoLGpqjx7vtQ/s03f0zR//0br/x
3131
github.com/aliyun/credentials-go v1.3.1/go.mod h1:8jKYhQuDawt8x2+fusqa1Y6mPxemTsBEN04dgcAcYz0=
3232
github.com/allegro/bigcache/v3 v3.1.0 h1:H2Vp8VOvxcrB91o86fUSVJFqeuz8kpyyB02eH3bSzwk=
3333
github.com/allegro/bigcache/v3 v3.1.0/go.mod h1:aPyh7jEvrog9zAwx5N7+JUQX5dZTSGpxF1LAR4dr35I=
34+
github.com/alyx/go-daddy v0.0.0-20240819232932-c2e4d209da9b h1:ITwV8o+xmGVD6IbBvjIlOoAsxX7me0ounq5UwzwdQlk=
35+
github.com/alyx/go-daddy v0.0.0-20240819232932-c2e4d209da9b/go.mod h1:JEEXFFpdZOowtBJN6+kUCQ+okHa4UfZtMBfWVRf71EM=
3436
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
3537
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
3638
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=

pkg/provider/godaddy.go

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package provider
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"strconv"
7+
"sync"
8+
"time"
9+
10+
"github.com/eryajf/cloud_dns_exporter/public/logger"
11+
"github.com/golang-module/carbon/v2"
12+
13+
"github.com/alyx/go-daddy/daddy"
14+
"github.com/eryajf/cloud_dns_exporter/public"
15+
)
16+
17+
type GodaddyDNS struct {
18+
account public.Account
19+
client *daddy.Client
20+
}
21+
22+
// NewGodaddyClient 初始化客户端
23+
func NewGodaddyClient(secretID, secretKey string) (*daddy.Client, error) {
24+
client, err := daddy.NewClient(secretID, secretKey, false)
25+
if err != nil {
26+
return nil, err
27+
}
28+
return client, nil
29+
}
30+
31+
// NewGodaddyDNS 创建 GodaddyDNS 实例
32+
func NewGodaddyDNS(account public.Account) (*GodaddyDNS, error) {
33+
client, err := NewGodaddyClient(account.SecretID, account.SecretKey)
34+
if err != nil {
35+
return nil, err
36+
}
37+
return &GodaddyDNS{
38+
account: account,
39+
client: client,
40+
}, nil
41+
}
42+
43+
// ListDomains 获取域名列表
44+
func (g *GodaddyDNS) ListDomains() ([]Domain, error) {
45+
gd, err := NewGodaddyDNS(public.Account{
46+
CloudProvider: g.account.CloudProvider,
47+
CloudName: g.account.CloudName,
48+
SecretID: g.account.SecretID,
49+
SecretKey: g.account.SecretKey,
50+
})
51+
if err != nil {
52+
return nil, err
53+
}
54+
g.client = gd.client
55+
var dataObj []Domain
56+
domains, err := g.getDomainList()
57+
if err != nil {
58+
return nil, err
59+
}
60+
for _, v := range domains {
61+
dataObj = append(dataObj, Domain{
62+
CloudProvider: g.account.CloudProvider,
63+
CloudName: g.account.CloudName,
64+
DomainID: strconv.Itoa(v.DomainID),
65+
DomainName: v.Domain,
66+
DomainRemark: v.Domain,
67+
DomainStatus: oneStatus(v.Status),
68+
CreatedDate: v.CreatedAt,
69+
ExpiryDate: v.Expires,
70+
DaysUntilExpiry: carbon.Now().DiffInDays(carbon.Parse(v.Expires)),
71+
})
72+
}
73+
return dataObj, nil
74+
}
75+
76+
// ListRecords 获取记录列表
77+
func (g *GodaddyDNS) ListRecords() ([]Record, error) {
78+
var (
79+
dataObj []Record
80+
domains []Domain
81+
wg sync.WaitGroup
82+
mu sync.Mutex
83+
)
84+
tcd, err := NewGodaddyDNS(public.Account{
85+
CloudProvider: g.account.CloudProvider,
86+
CloudName: g.account.CloudName,
87+
SecretID: g.account.SecretID,
88+
SecretKey: g.account.SecretKey,
89+
})
90+
if err != nil {
91+
return nil, err
92+
}
93+
g.client = tcd.client
94+
rst, err := public.Cache.Get(public.DomainList + "_" + g.account.CloudProvider + "_" + g.account.CloudName)
95+
if err != nil {
96+
return nil, err
97+
}
98+
err = json.Unmarshal(rst, &domains)
99+
if err != nil {
100+
return nil, err
101+
}
102+
results := make(map[string][]daddy.DNSRecord)
103+
ticker := time.NewTicker(time.Second)
104+
for _, domain := range domains {
105+
wg.Add(1)
106+
go func(domain string) {
107+
defer wg.Done()
108+
<-ticker.C
109+
records, err := g.getRecordList(domain)
110+
if err != nil {
111+
logger.Error(fmt.Sprintf("[ %s_%s ] get record list failed: %v", g.account.CloudProvider, g.account.CloudName, err))
112+
}
113+
if len(records) == 0 {
114+
return
115+
}
116+
mu.Lock()
117+
results[domain] = records
118+
mu.Unlock()
119+
}(domain.DomainName)
120+
}
121+
wg.Wait()
122+
for domain, records := range results {
123+
for _, v := range records {
124+
dataObj = append(dataObj, Record{
125+
CloudProvider: g.account.CloudProvider,
126+
CloudName: g.account.CloudName,
127+
DomainName: domain,
128+
RecordID: v.Data,
129+
RecordType: v.Type,
130+
RecordName: v.Name,
131+
RecordValue: v.Data,
132+
RecordTTL: strconv.Itoa(v.TTL),
133+
RecordWeight: strconv.Itoa(v.Weight),
134+
RecordStatus: "enable",
135+
RecordRemark: v.Name,
136+
FullRecord: v.Name + "." + domain,
137+
})
138+
}
139+
}
140+
return dataObj, nil
141+
}
142+
143+
// https://developer.godaddy.com/doc/endpoint/domains
144+
// GetDomainList 获取云解析中域名列表
145+
func (g *GodaddyDNS) getDomainList() ([]daddy.DomainSummary, error) {
146+
domains, err := g.client.Domains.List(nil, nil, 0, "", nil, "")
147+
if err != nil {
148+
return nil, err
149+
}
150+
151+
return domains, nil
152+
}
153+
154+
// https://developer.godaddy.com/doc/endpoint/domains
155+
// RecordList 域名记录列表
156+
func (g *GodaddyDNS) getRecordList(domain string) ([]daddy.DNSRecord, error) {
157+
// TODO 目前写死的获取500条记录
158+
rds, err := g.client.Domains.GetRecords(domain, "", "", 0, 500)
159+
if err != nil {
160+
fmt.Printf("Error listing records: %v\n", err)
161+
}
162+
return rds, err
163+
}

pkg/provider/provider.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ func init() {
3232
},
3333
}
3434
})
35+
Factory.Register(public.GodaddyDnsProvider, func(account map[string]string) DNSProvider {
36+
return &GodaddyDNS{
37+
account: public.Account{
38+
CloudProvider: public.GodaddyDnsProvider,
39+
CloudName: account["name"],
40+
SecretID: account["secretId"],
41+
SecretKey: account["secretKey"],
42+
},
43+
}
44+
})
3545
}
3646

3747
// Doamin 域名信息
@@ -123,7 +133,7 @@ func (f *DNSProviderFactory) Create(cloudProvider string, account map[string]str
123133
// 统一记录状态的值
124134
func oneStatus(status string) string {
125135
// tencent 的记录状态是 ENABLE 和 DISABLE
126-
if status == "ENABLE" {
136+
if status == "ENABLE" || status == "ACTIVE" {
127137
return "enable"
128138
}
129139
if status == "DISABLE" {

public/public.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const (
2222
// Cloud Providers
2323
TencentDnsProvider string = "tencent"
2424
AliyunDnsProvider string = "aliyun"
25+
GodaddyDnsProvider string = "godaddy"
2526
HuaweiDnsProvider string = "huawei"
2627
// Metrics Name
2728
DomainList string = "domain_list"

0 commit comments

Comments
 (0)