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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user