func cleanupDomain(r53 *route53.Route53, id string) { // delete all non-default SOA/NS records rrsets, err := cli53.ListAllRecordSets(r53, id) fatalIfErr(err) changes := []*route53.Change{} for _, rrset := range rrsets { if *rrset.Type != "NS" && *rrset.Type != "SOA" { change := &route53.Change{ Action: aws.String("DELETE"), ResourceRecordSet: rrset, } changes = append(changes, change) } } if len(changes) > 0 { req2 := route53.ChangeResourceRecordSetsInput{ HostedZoneId: &id, ChangeBatch: &route53.ChangeBatch{ Changes: changes, }, } _, err = r53.ChangeResourceRecordSets(&req2) if err != nil { fmt.Printf("Warning: cleanup failed - %s\n", err) } } req3 := route53.DeleteHostedZoneInput{Id: &id} _, err = r53.DeleteHostedZone(&req3) if err != nil { fmt.Printf("Warning: cleanup failed - %s\n", err) } }
func deleteRoute53RecordSet(conn *route53.Route53, input *route53.ChangeResourceRecordSetsInput) (interface{}, error) { wait := resource.StateChangeConf{ Pending: []string{"rejected"}, Target: []string{"accepted"}, Timeout: 5 * time.Minute, MinTimeout: 1 * time.Second, Refresh: func() (interface{}, string, error) { resp, err := conn.ChangeResourceRecordSets(input) if err != nil { if r53err, ok := err.(awserr.Error); ok { if r53err.Code() == "PriorRequestNotComplete" { // There is some pending operation, so just retry // in a bit. return 42, "rejected", nil } if r53err.Code() == "InvalidChangeBatch" { // This means that the record is already gone. return resp, "accepted", nil } } return 42, "failure", err } return resp, "accepted", nil }, } return wait.WaitForState() }
func upsertRecordOnRoute53(ipAddress string, fqdn string, svc *route53.Route53, verbose bool) { // Extract the domain from the fully qualified domain name r, _ := regexp.Compile("^([^\x2E]*)\x2E(.*)$") toks := r.FindStringSubmatch(fqdn) domain := toks[2] // http://docs.aws.amazon.com/sdk-for-go/api/service/route53/Route53.html#ListHostedZonesByName-instance_method resources, err := svc.ListHostedZonesByName(&route53.ListHostedZonesByNameInput{ DNSName: aws.String(domain + "."), MaxItems: aws.String("1"), }) if err != nil { fmt.Println("ERR: err.Error()", err) os.Exit(1) } if len(resources.HostedZones) != 1 { fmt.Printf("ERR: Could not find the domain %s\n", domain) os.Exit(1) } if *resources.DNSName != domain+"." { fmt.Printf("ERR: Could not find the domain %s - %s \n", domain, *resources.DNSName) os.Exit(1) } zoneIDToks := strings.Split(*resources.HostedZones[0].Id, "/") zoneID := zoneIDToks[len(zoneIDToks)-1] resp, err := svc.ListResourceRecordSets(&route53.ListResourceRecordSetsInput{ StartRecordName: aws.String(fqdn), StartRecordType: aws.String("A"), HostedZoneId: aws.String(zoneID), MaxItems: aws.String("1"), }) if err != nil { fmt.Println(err.Error()) os.Exit(1) } var foundResource bool if len(resp.ResourceRecordSets) != 1 { foundResource = false } else { foundResource = *resp.ResourceRecordSets[0].Name == fqdn+"." if foundResource { for _, record := range resp.ResourceRecordSets[0].ResourceRecords { if *record.Value == ipAddress { if verbose { fmt.Printf("INFO: %s already registered in route53 as %s\n", ipAddress, fqdn) } return } } } } // Make an A-record: resourceRecordSet := &route53.ResourceRecordSet{ Name: aws.String(fqdn + "."), Type: aws.String("A"), ResourceRecords: []*route53.ResourceRecord{ &route53.ResourceRecord{ Value: aws.String(ipAddress), }, }, TTL: aws.Int64(300), } // Wrap it as an UPSERT upsert := []*route53.Change{&route53.Change{ Action: aws.String("UPSERT"), ResourceRecordSet: resourceRecordSet, }} // Put it into a pretty envelope with a stamp for route53#zoneId and change ticket params := route53.ChangeResourceRecordSetsInput{ ChangeBatch: &route53.ChangeBatch{ Changes: upsert, }, HostedZoneId: aws.String(zoneID), } // Post it changeResp, err := svc.ChangeResourceRecordSets(¶ms) if err != nil { fmt.Println("ERR: ", err.Error(), changeResp) os.Exit(1) } // Done if verbose { fmt.Printf("INFO: Submitted change for zoneId %s to register %s as %s\n", zoneID, ipAddress, fqdn) } }