go-ddns-svc/route/api/dns.go

118 lines
2.3 KiB
Go

package api
import (
"fmt"
"log"
"strings"
"git.trj.tw/golang/go-ddns-svc/module/apis/aws"
"git.trj.tw/golang/go-ddns-svc/module/context"
"git.trj.tw/golang/go-ddns-svc/module/tools"
awssdk "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/route53"
)
// RecordData -
type RecordData struct {
Type string `json:"type"`
Name string `json:"name"`
}
// DomainData -
type DomainData struct {
Name string `json:"name"`
Records []RecordData `json:"records"`
}
// UpdateDDNSBody -
type UpdateDDNSBody struct {
Domain []DomainData `json:"domain"`
}
// UpdateDDNS -
func UpdateDDNS(c *context.Context) {
body := UpdateDDNSBody{}
err := c.BindData(&body)
if err != nil {
log.Println("bind data error :: ", err)
c.DataFormat(nil)
return
}
ip := tools.RemoteIP(c.Request)
log.Println("Client IP :: ", ip)
if len(body.Domain) == 0 {
c.DataFormat(nil)
return
}
domains := make([]string, 0, len(body.Domain))
for _, v := range body.Domain {
domains = append(domains, v.Name)
}
zones, err := aws.QueryDomain(domains)
if err != nil {
log.Println("get zone error :: ", err)
c.ServerError(nil)
return
}
for _, it := range zones {
for _, domain := range body.Domain {
if domain.Name[len(domain.Name)-1:] != "." {
domain.Name += "."
}
if it.Name == domain.Name {
sets, err := getRecordSet(it, domain.Records)
if err != nil {
log.Println("get record error :: ", err)
continue
}
// compare ip
changeSet := make([]*route53.ResourceRecordSet, 0, len(sets))
for _, set := range sets {
if *set.ResourceRecords[0].Value != ip {
set.ResourceRecords[0].Value = awssdk.String(ip)
changeSet = append(changeSet, set)
}
}
if len(changeSet) == 0 {
break
}
aws.UpdateRecord(it.ID, changeSet)
}
}
}
c.Success(nil)
}
func getRecordSet(zone *aws.ZoneData, records []RecordData) ([]*route53.ResourceRecordSet, error) {
names := make([]string, 0, len(records))
for _, v := range records {
names = append(names, fmt.Sprintf("%s.%s", v.Name, zone.Name))
}
sets := make([]*route53.ResourceRecordSet, 0, len(records))
data, err := aws.GetRecord(zone.ID, names)
for _, it := range data {
for _, record := range records {
if *it.Type == strings.ToUpper(record.Type) {
sets = append(sets, it)
}
}
}
return sets, err
}