add domain zone and record get / update

This commit is contained in:
Jay 2018-01-22 17:48:49 +08:00
parent 9671dc7422
commit aa828fe5b2
4 changed files with 277 additions and 2 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
config.yml

4
config.default.yml Normal file
View File

@ -0,0 +1,4 @@
domains:
- name: domain.name
subdomain:
- subbname

225
main.go
View File

@ -1,5 +1,226 @@
package main
func main() {
println("Hello")
import (
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"regexp"
"time"
"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
}
func main() {
newR53()
config = setting.LoadConfig(confpath)
fmt.Println(config)
ip = getMyIP()
if ok, err := checkIP(ip); err != nil || !ok {
println("ip check fail")
checkErr(err)
}
println(ip)
mainLoc := make(chan bool)
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])
go func() {
for {
for _, it := range domains {
it.updateRecord()
}
time.Sleep(time.Duration.Minutes * 5)
}
}()
<-mainLoc
}
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 {
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 {
return
}
changeInput := &route53.ChangeResourceRecordSetsInput{
HostedZoneId: it.Zone.Id,
ChangeBatch: &route53.ChangeBatch{
Changes: chs,
},
}
_, err = r53.ChangeResourceRecordSets(changeInput)
checkErr(err)
}
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)
}
}

49
modules/setting.go Normal file
View File

@ -0,0 +1,49 @@
package setting
import (
"io/ioutil"
"log"
"os"
"path"
"path/filepath"
"gopkg.in/yaml.v2"
)
type Config struct {
Domains []struct {
Name string `yaml:"name"`
Sub []string `yaml:"subdomain,flow"`
} `yaml:"domains"`
}
func LoadConfig(fp ...string) *Config {
var p string
if len(fp) > 0 && len(fp[0]) > 0 {
p = fp[0]
} else {
dir, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
p = path.Join(dir, "config.yml")
}
zone := &Config{}
p, err := filepath.Abs(p)
if err != nil {
log.Fatal(err)
}
data, err := ioutil.ReadFile(p)
if err != nil {
log.Fatal(err)
}
err = yaml.Unmarshal([]byte(data), &zone)
if err != nil {
log.Fatal(err)
}
return zone
}