Skip to content

Commit

Permalink
Merge pull request #359 from terraform-providers/paddy_95_dns_ns
Browse files Browse the repository at this point in the history
dns: Add special handling for ns records.
  • Loading branch information
paddycarver authored Nov 8, 2017
2 parents 624a737 + 4a342ca commit 8b2486c
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
35 changes: 35 additions & 0 deletions google/resource_dns_record_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,33 @@ func resourceDnsRecordSetCreate(d *schema.ResourceData, meta interface{}) error
},
}

// we need to replace NS record sets in the same call. That means
// we need to list all the current NS record sets attached to the
// zone and add them to the change as deletions. We can't just add
// new NS record sets, or we'll get an error about the NS record set
// already existing; see terraform-providers/terraform-provider-google#95.
// We also can't just remove the NS recordsets on creation, as at
// least one is required. So the solution is to "update in place" by
// putting the addition and the removal in the same API call.
if d.Get("type").(string) == "NS" {
log.Printf("[DEBUG] DNS record list request for %q", zone)
res, err := config.clientDns.ResourceRecordSets.List(project, zone).Do()
if err != nil {
return fmt.Errorf("Error retrieving record sets for %q: %s", zone, err)
}
var deletions []*dns.ResourceRecordSet

for _, record := range res.Rrsets {
if record.Type != "NS" {
continue
}
deletions = append(deletions, record)
}
if len(deletions) > 0 {
chg.Deletions = deletions
}
}

log.Printf("[DEBUG] DNS Record create request: %#v", chg)
chg, err = config.clientDns.Changes.Create(project, zone, chg).Do()
if err != nil {
Expand Down Expand Up @@ -135,6 +162,14 @@ func resourceDnsRecordSetRead(d *schema.ResourceData, meta interface{}) error {
}

func resourceDnsRecordSetDelete(d *schema.ResourceData, meta interface{}) error {

// NS records must always have a value, so we short-circuit delete
// this allows terraform delete to work, but may have unexpected
// side-effects when deleting just that record set.
if d.Get("type").(string) == "NS" {
log.Println("[DEBUG] NS records can't be deleted due to API restrictions, so they're being left in place. See https://www.terraform.io/docs/providers/google/r/dns_record_set.html for more information.")
return nil
}
config := meta.(*Config)

project, err := getProject(d, config)
Expand Down
35 changes: 35 additions & 0 deletions google/resource_dns_record_set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,24 @@ func TestAccDnsRecordSet_changeType(t *testing.T) {
})
}

func TestAccDnsRecordSet_ns(t *testing.T) {
zoneName := fmt.Sprintf("dnszone-test-ns-%s", acctest.RandString(10))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckDnsRecordSetDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccDnsRecordSet_ns(zoneName, 300),
Check: resource.ComposeTestCheckFunc(
testAccCheckDnsRecordSetExists(
"google_dns_record_set.foobar", zoneName),
),
},
},
})
}

func testAccCheckDnsRecordSetDestroy(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)

Expand Down Expand Up @@ -157,6 +175,23 @@ func testAccDnsRecordSet_basic(zoneName string, addr2 string, ttl int) string {
`, zoneName, addr2, ttl)
}

func testAccDnsRecordSet_ns(name string, ttl int) string {
return fmt.Sprintf(`
resource "google_dns_managed_zone" "parent-zone" {
name = "%s"
dns_name = "hashicorptest.com."
description = "Test Description"
}
resource "google_dns_record_set" "foobar" {
managed_zone = "${google_dns_managed_zone.parent-zone.name}"
name = "hashicorptest.com."
type = "NS"
rrdatas = ["ns.hashicorp.services.", "ns2.hashicorp.services."]
ttl = %d
}
`, name, ttl)
}

func testAccDnsRecordSet_bigChange(zoneName string, ttl int) string {
return fmt.Sprintf(`
resource "google_dns_managed_zone" "parent-zone" {
Expand Down
6 changes: 6 additions & 0 deletions website/docs/r/dns_record_set.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ description: |-

Manages a set of DNS records within Google Cloud DNS.

~> **Note:** The Google Cloud DNS API requires NS records be present at all
times. To accommodate this, when creating NS records, the default records
Google automatically creates will be silently overwritten. Also, when
destroying NS records, Terraform will not actually remove NS records, but will
report that it did.

## Example Usage

### Binding a DNS name to the ephemeral IP of a new instance:
Expand Down

0 comments on commit 8b2486c

Please sign in to comment.