add domain zone and record get / update
This commit is contained in:
parent
9671dc7422
commit
aa828fe5b2
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
config.yml
|
4
config.default.yml
Normal file
4
config.default.yml
Normal file
@ -0,0 +1,4 @@
|
||||
domains:
|
||||
- name: domain.name
|
||||
subdomain:
|
||||
- subbname
|
225
main.go
225
main.go
@ -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
49
modules/setting.go
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user