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 } 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) 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]) 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 { 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 { 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) 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) } }