go-aws-dns/main.go

222 lines
4.0 KiB
Go
Raw Permalink Normal View History

2018-01-21 16:27:00 +00:00
package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"regexp"
"git.trj.tw/golang/go-aws-dns/modules"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/route53"
)
var (
r53 *route53.Route53
config *setting.Config
confpath string
domains []*Domains
ip string
)
func init() {
println("init")
flag.StringVar(&confpath, "config", "", "config file path (default pwd/config.yml)")
flag.StringVar(&confpath, "f", "", "config file path (short)(default pwd/config.yml)")
flag.Parse()
}
type Domains struct {
Name string
Zone *route53.HostedZone
Sub []string
}
2018-01-21 16:27:00 +00:00
func main() {
newR53()
config = setting.LoadConfig(confpath)
fmt.Println(config)
2018-09-10 02:44:23 +00:00
ip = getMyIP()
if ok, err := checkIP(ip); err != nil || !ok {
println("ip check fail")
checkErr(err)
}
println(ip)
var tmp []string
for _, it := range config.Domains {
domains = append(domains, &Domains{
Name: it.Name,
Sub: it.Sub,
})
name := it.Name
if name[len(name)-1:] != "." {
name += "."
}
tmp = append(tmp, name)
}
zones, err := getZones(tmp)
checkErr(err)
for _, it := range domains {
for _, it2 := range zones {
tmp := *it2.Name
if tmp[len(tmp)-1:] == "." {
tmp = tmp[0 : len(tmp)-1]
}
if it.Name == tmp {
it.Zone = it2
}
}
}
fmt.Println(domains[0])
2018-09-26 11:42:38 +00:00
for _, it := range domains {
it.updateRecord()
}
}
func newR53() {
sess, err := session.NewSession(&aws.Config{
Region: aws.String("us-east-2"),
Credentials: credentials.NewSharedCredentials("", "mtfos"),
})
checkErr(err)
r53 = route53.New(sess)
}
func checkIP(ip string) (bool, error) {
if len(ip) == 0 {
return false, nil
}
if ok, err := regexp.MatchString("^(\\d){1,3}\\.(\\d){1,3}\\.(\\d){1,3}\\.(\\d){1,3}$", ip); err != nil || !ok {
return false, err
}
return true, nil
}
func getMyIP() string {
res, err := http.Get("http://ipv4.trj.tw/")
checkErr(err)
defer res.Body.Close()
if res.StatusCode != 200 {
return ""
}
body, err := ioutil.ReadAll(res.Body)
checkErr(err)
return string(body)
}
func (it *Domains) updateRecord() {
if len(it.Sub) == 0 {
2018-01-23 01:35:49 +00:00
println("no subdomain")
return
}
listInput := &route53.ListResourceRecordSetsInput{
HostedZoneId: it.Zone.Id,
}
ls, err := r53.ListResourceRecordSets(listInput)
checkErr(err)
var chs []*route53.Change
for _, item := range ls.ResourceRecordSets {
for _, item2 := range it.Sub {
tmp := item2 + "." + it.Name
if tmp[len(tmp)-1:] != "." {
tmp += "."
}
if *item.Name == tmp {
if *item.Type == "A" && *item.ResourceRecords[0].Value != ip {
item.ResourceRecords[0].Value = aws.String(ip)
chs = append(chs, &route53.Change{
ResourceRecordSet: item,
Action: aws.String("UPSERT"),
})
}
}
}
}
if len(chs) == 0 {
2018-01-23 01:35:49 +00:00
println("ip not change or not type a record")
return
}
changeInput := &route53.ChangeResourceRecordSetsInput{
HostedZoneId: it.Zone.Id,
ChangeBatch: &route53.ChangeBatch{
Changes: chs,
},
}
_, err = r53.ChangeResourceRecordSets(changeInput)
checkErr(err)
2018-01-23 01:35:49 +00:00
println("update ok")
}
func getZones(names []string) (zones []*route53.HostedZone, err error) {
if len(names) == 0 {
return
}
input := &route53.ListHostedZonesInput{}
list, err := r53.ListHostedZones(input)
if err != nil {
return
}
for _, item := range list.HostedZones {
for _, name := range names {
if name == *item.Name {
zones = append(zones, item)
}
}
}
return
}
func getRecords(id *string, names []string) (records []*route53.ResourceRecordSet, err error) {
if len(names) == 0 {
return
}
input := &route53.ListResourceRecordSetsInput{
HostedZoneId: id,
}
list, err := r53.ListResourceRecordSets(input)
if err != nil {
return
}
for _, item := range list.ResourceRecordSets {
for _, name := range names {
if name == *item.Name {
records = append(records, item)
}
}
}
return
}
func checkErr(err error) {
if err != nil {
log.Fatal(err)
}
2018-01-21 16:27:00 +00:00
}