168 lines
3.5 KiB
Go
168 lines
3.5 KiB
Go
package aws
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"git.trj.tw/golang/go-ddns-svc/module/config"
|
|
"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"
|
|
)
|
|
|
|
// AWSClient -
|
|
type AWSClient struct {
|
|
Session *session.Session
|
|
Config *aws.Config
|
|
R53 *route53.Route53
|
|
}
|
|
|
|
var client *AWSClient
|
|
|
|
// Error messages
|
|
var (
|
|
ErrNoClient = errors.New("client not init")
|
|
ErrNoZone = errors.New("no hosted zones")
|
|
)
|
|
|
|
// NewAWS -
|
|
func NewAWS() error {
|
|
conf := config.GetConfig()
|
|
awsConf := &aws.Config{}
|
|
awsConf.Region = aws.String("us-east-1")
|
|
var sess *session.Session
|
|
|
|
if conf.AWS.SharedConfig {
|
|
if len(conf.AWS.SharedName) == 0 {
|
|
return errors.New("aws shared config name empty")
|
|
}
|
|
awsConf.Credentials = credentials.NewSharedCredentials("", conf.AWS.SharedName)
|
|
} else {
|
|
awsConf.Credentials = credentials.NewStaticCredentials(conf.AWS.AccessKey, conf.AWS.SecretKey, "")
|
|
}
|
|
sess = session.New(awsConf)
|
|
|
|
client = &AWSClient{}
|
|
client.Session = sess
|
|
client.Config = awsConf
|
|
client.R53 = route53.New(client.Session)
|
|
|
|
return nil
|
|
}
|
|
|
|
// ZoneData -
|
|
type ZoneData struct {
|
|
ID *string
|
|
Name string
|
|
}
|
|
|
|
// QueryDomain -
|
|
func QueryDomain(name []string) ([]*ZoneData, error) {
|
|
if client == nil {
|
|
return nil, ErrNoClient
|
|
}
|
|
domains := make([]string, 0, len(name))
|
|
if len(name) == 0 {
|
|
return nil, errors.New("no input domain name")
|
|
}
|
|
for _, n := range name {
|
|
if len(n) > 0 {
|
|
if n[len(n)-1:] != "." {
|
|
n += "."
|
|
}
|
|
domains = append(domains, n)
|
|
}
|
|
}
|
|
if len(domains) == 0 {
|
|
return nil, errors.New("no input domain name")
|
|
}
|
|
|
|
input := &route53.ListHostedZonesInput{}
|
|
zoneOut, err := client.R53.ListHostedZones(input)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(zoneOut.HostedZones) == 0 {
|
|
return nil, ErrNoZone
|
|
}
|
|
|
|
zones := make([]*ZoneData, 0)
|
|
for _, it := range zoneOut.HostedZones {
|
|
for _, domain := range domains {
|
|
if *it.Name == domain {
|
|
zone := &ZoneData{
|
|
ID: it.Id,
|
|
Name: domain,
|
|
}
|
|
zones = append(zones, zone)
|
|
}
|
|
}
|
|
}
|
|
return zones, nil
|
|
}
|
|
|
|
// GetRecord -
|
|
func GetRecord(id *string, names []string) ([]*route53.ResourceRecordSet, error) {
|
|
if id == nil {
|
|
return nil, errors.New("no id input")
|
|
}
|
|
if len(names) == 0 {
|
|
return nil, errors.New("no record names")
|
|
}
|
|
records := make([]string, 0)
|
|
for _, v := range names {
|
|
if len(v) > 0 {
|
|
records = append(records, v)
|
|
}
|
|
}
|
|
|
|
input := &route53.ListResourceRecordSetsInput{}
|
|
input.SetHostedZoneId(*id)
|
|
resOut, err := client.R53.ListResourceRecordSets(input)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(resOut.ResourceRecordSets) == 0 {
|
|
return nil, errors.New("no record sets")
|
|
}
|
|
|
|
sets := make([]*route53.ResourceRecordSet, 0)
|
|
for _, it := range resOut.ResourceRecordSets {
|
|
for _, name := range records {
|
|
if *it.Name == name {
|
|
sets = append(sets, it)
|
|
}
|
|
}
|
|
}
|
|
|
|
return sets, nil
|
|
}
|
|
|
|
// UpdateRecord -
|
|
func UpdateRecord(zoneID *string, sets []*route53.ResourceRecordSet) error {
|
|
if len(sets) == 0 {
|
|
return errors.New("no change set input")
|
|
}
|
|
changeSets := make([]*route53.Change, 0)
|
|
|
|
for _, v := range sets {
|
|
changeSets = append(changeSets, &route53.Change{
|
|
ResourceRecordSet: v,
|
|
Action: aws.String("UPSERT"),
|
|
})
|
|
}
|
|
|
|
changeInput := &route53.ChangeResourceRecordSetsInput{
|
|
HostedZoneId: zoneID,
|
|
ChangeBatch: &route53.ChangeBatch{
|
|
Changes: changeSets,
|
|
},
|
|
}
|
|
_, err := client.R53.ChangeResourceRecordSets(changeInput)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|