github.com/defang-io/defang/src@v0.0.0-20240505002154-bdf411911834/pkg/clouds/aws/route53.go (about)

     1  package aws
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"strings"
     7  	"time"
     8  
     9  	"github.com/aws/aws-sdk-go-v2/aws"
    10  	"github.com/aws/aws-sdk-go-v2/service/route53"
    11  	"github.com/aws/aws-sdk-go-v2/service/route53/types"
    12  )
    13  
    14  var (
    15  	ErrNoZoneFound   = errors.New("no zone found")
    16  	ErrNoRecordFound = errors.New("no record found")
    17  )
    18  
    19  func GetZoneIdFromDomain(ctx context.Context, domain string, r53 *route53.Client) (string, error) {
    20  	params := &route53.ListHostedZonesByNameInput{
    21  		DNSName:  aws.String(domain),
    22  		MaxItems: aws.Int32(1),
    23  	}
    24  	resp, err := r53.ListHostedZonesByName(ctx, params)
    25  	if err != nil {
    26  		return "", err
    27  	}
    28  	if len(resp.HostedZones) == 0 {
    29  		return "", ErrNoZoneFound
    30  	}
    31  
    32  	// ListHostedZonesByName returns all zones that is after the specified domain, we need to check the domain is the same
    33  	zone := resp.HostedZones[0]
    34  	if !isSameDomain(*zone.Name, domain) {
    35  		return "", ErrNoZoneFound
    36  	}
    37  
    38  	return *zone.Id, nil
    39  }
    40  
    41  func CreateZone(ctx context.Context, domain string, r53 *route53.Client) (string, error) {
    42  	params := &route53.CreateHostedZoneInput{
    43  		Name:            aws.String(domain),
    44  		CallerReference: aws.String(domain + time.Now().String()),
    45  		HostedZoneConfig: &types.HostedZoneConfig{
    46  			Comment: aws.String("Created by defang cli"),
    47  		},
    48  	}
    49  	resp, err := r53.CreateHostedZone(ctx, params)
    50  	if err != nil {
    51  		return "", err
    52  	}
    53  	return *resp.HostedZone.Id, nil
    54  }
    55  
    56  func GetRecordsValue(ctx context.Context, zoneId, name string, recordType types.RRType, r53 *route53.Client) ([]string, error) {
    57  	listInput := &route53.ListResourceRecordSetsInput{
    58  		HostedZoneId:    aws.String(zoneId),
    59  		StartRecordName: aws.String(name),
    60  		StartRecordType: recordType,
    61  		MaxItems:        aws.Int32(1),
    62  	}
    63  
    64  	listResp, err := r53.ListResourceRecordSets(ctx, listInput)
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	if len(listResp.ResourceRecordSets) == 0 {
    70  		return nil, ErrNoRecordFound
    71  	}
    72  
    73  	records := listResp.ResourceRecordSets[0].ResourceRecords
    74  	values := make([]string, len(records))
    75  	for i, record := range records {
    76  		values[i] = *record.Value
    77  	}
    78  	return values, nil
    79  }
    80  
    81  func isSameDomain(domain1 string, domain2 string) bool {
    82  	return strings.TrimSuffix(domain1, ".") == strings.TrimSuffix(domain2, ".")
    83  }