This repository has been archived by the owner on Dec 12, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathmain.go
143 lines (118 loc) · 3.36 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package main
import (
"encoding/json"
"flag"
"github.com/ahmetb/go-linq/v3"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/services/alidns"
"io/ioutil"
"log"
"net/http"
"os"
"path"
"strings"
"time"
)
var commandModel CommandModel
var configModel ConfigurationModel
func main() {
initCommandModel()
loadConfig()
if commandModel.Interval == nil || *commandModel.Interval == 0 {
update()
return
}
intervalFunction()
}
func update() {
publicIp := getPublicIp()
subDomains := getSubDomains()
for _, sub := range subDomains {
if sub.Value != publicIp {
// 更新域名绑定的 IP 地址。
sub.Value = publicIp
sub.TTL = linq.From(*configModel.SubDomains).FirstWith(func(subDomain interface{}) bool {
return subDomain.(SubDomainModel).Name == sub.RR
}).(SubDomainModel).Interval
updateSubDomain(&sub)
}
}
log.Printf("域名记录更新成功...")
}
func intervalFunction() {
tick := time.Tick(time.Second * time.Duration(*commandModel.Interval))
for {
select {
case <-tick:
update()
}
}
}
func initCommandModel() {
commandModel.FilePath = flag.String("f", "", "指定自定义的配置文件,请传入配置文件的路径。")
commandModel.Interval = flag.Int("i", 0, "指定程序的自动检测周期,单位是秒。")
flag.Parse()
}
func loadConfig() {
var configFile string
if *commandModel.FilePath == "" {
dir, _ := os.Getwd()
configFile = path.Join(dir, "settings.json")
} else {
configFile = *commandModel.FilePath
}
// 打开配置文件,并进行反序列化。
f, err := os.Open(configFile)
if err != nil {
log.Fatalf("无法打开文件:%s", err)
os.Exit(-1)
}
defer f.Close()
data, _ := ioutil.ReadAll(f)
if err := json.Unmarshal(data, &configModel); err != nil {
log.Fatalf("数据反序列化失败:%s", err)
os.Exit(-1)
}
}
func getPublicIp() string {
resp, err := http.Get(GetPublicIpUrl)
if err != nil {
log.Printf("获取公网 IP 出现错误,错误信息:%s", err)
os.Exit(-1)
}
defer resp.Body.Close()
bytes, _ := ioutil.ReadAll(resp.Body)
return strings.Replace(string(bytes), "\n", "", -1)
}
func getSubDomains() []alidns.Record {
client, err := alidns.NewClientWithAccessKey("cn-hangzhou", configModel.AccessId, configModel.AccessKey)
request := alidns.CreateDescribeDomainRecordsRequest()
request.Scheme = "https"
request.DomainName = configModel.MainDomain
response, err := client.DescribeDomainRecords(request)
if err != nil {
log.Println(err.Error())
}
// 过滤符合条件的子域名信息。
var queryResult []alidns.Record
linq.From(response.DomainRecords.Record).Where(func(c interface{}) bool {
return linq.From(*configModel.SubDomains).Select(func(x interface{}) interface{} {
return x.(SubDomainModel).Name
}).Contains(c.(alidns.Record).RR)
}).ToSlice(&queryResult)
return queryResult
}
func updateSubDomain(subDomain *alidns.Record) {
client, err := alidns.NewClientWithAccessKey("cn-hangzhou", configModel.AccessId, configModel.AccessKey)
request := alidns.CreateUpdateDomainRecordRequest()
request.Scheme = "https"
request.RecordId = subDomain.RecordId
request.RR = subDomain.RR
request.Type = subDomain.Type
request.Value = subDomain.Value
request.TTL = requests.NewInteger64(subDomain.TTL)
_, err = client.UpdateDomainRecord(request)
if err != nil {
log.Print(err.Error())
}
}