Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add force_destroy to google_dns_managed_zone #7289

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/3917.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
dns: added `force_destroy` option to `google_dns_managed_zone` to delete records created outside of Terraform
```
83 changes: 83 additions & 0 deletions google/resource_dns_managed_zone.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/helper/hashcode"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"google.golang.org/api/dns/v1"
)

func resourceDNSManagedZone() *schema.Resource {
Expand Down Expand Up @@ -256,6 +257,11 @@ defined by the server`,
Type: schema.TypeString,
},
},
"force_destroy": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"project": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -422,6 +428,10 @@ func resourceDNSManagedZoneRead(d *schema.ResourceData, meta interface{}) error
return handleNotFoundError(err, d, fmt.Sprintf("DNSManagedZone %q", d.Id()))
}

// Explicitly set virtual fields to default values if unset
if _, ok := d.GetOk("force_destroy"); !ok {
d.Set("force_destroy", false)
}
if err := d.Set("project", project); err != nil {
return fmt.Errorf("Error reading ManagedZone: %s", err)
}
Expand Down Expand Up @@ -549,6 +559,76 @@ func resourceDNSManagedZoneDelete(d *schema.ResourceData, meta interface{}) erro
}

var obj map[string]interface{}
if d.Get("force_destroy").(bool) {
zone := d.Get("name").(string)
token := ""
for paginate := true; paginate; {
var resp *dns.ResourceRecordSetsListResponse
if token == "" {
resp, err = config.clientDns.ResourceRecordSets.List(project, zone).Do()
if err != nil {
return fmt.Errorf("Error reading ResourceRecordSets: %s", err)
}
} else {
resp, err = config.clientDns.ResourceRecordSets.List(project, zone).PageToken(token).Do()
if err != nil {
return fmt.Errorf("Error reading ResourceRecordSets: %s", err)
}
}

for _, rr := range resp.Rrsets {
// Build the change
chg := &dns.Change{
Deletions: []*dns.ResourceRecordSet{
{
Name: rr.Name,
Type: rr.Type,
Ttl: rr.Ttl,
Rrdatas: rr.Rrdatas,
},
},
}

if rr.Type == "NS" {
mz, err := config.clientDns.ManagedZones.Get(project, zone).Do()
if err != nil {
return fmt.Errorf("Error retrieving managed zone %q from %q: %s", zone, project, err)
}
domain := mz.DnsName

if domain == rr.Name {
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.")
continue
}
}

if rr.Type == "SOA" {
log.Println("[DEBUG] SOA records can't be deleted due to API restrictions, so they're being left in place.")
continue
}

log.Printf("[DEBUG] DNS Record delete request via MZ: %#v", chg)
chg, err = config.clientDns.Changes.Create(project, zone, chg).Do()
if err != nil {
return fmt.Errorf("Unable to delete ResourceRecordSets: %s", err)
}

w := &DnsChangeWaiter{
Service: config.clientDns,
Change: chg,
Project: project,
ManagedZone: zone,
}
_, err = w.Conf().WaitForState()
if err != nil {
return fmt.Errorf("Error waiting for Google DNS change: %s", err)
}
}

token = resp.NextPageToken
paginate = token != ""
}
}
log.Printf("[DEBUG] Deleting ManagedZone %q", d.Id())

// err == nil indicates that the billing_project value was found
Expand Down Expand Up @@ -582,6 +662,9 @@ func resourceDNSManagedZoneImport(d *schema.ResourceData, meta interface{}) ([]*
}
d.SetId(id)

// Explicitly set virtual fields to default values on import
d.Set("force_destroy", false)

return []*schema.ResourceData{d}, nil
}

Expand Down
124 changes: 0 additions & 124 deletions google/resource_dns_managed_zone_sweeper_test.go

This file was deleted.

85 changes: 85 additions & 0 deletions google/resource_dns_managed_zone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
"google.golang.org/api/dns/v1"
)

func TestAccDNSManagedZone_update(t *testing.T) {
Expand Down Expand Up @@ -149,6 +151,89 @@ func TestAccDNSManagedZone_privateForwardingUpdate(t *testing.T) {
})
}

func TestAccDNSManagedZone_forceDestroy(t *testing.T) {
//t.Parallel()

zoneSuffix := randString(t, 10)
project := getTestProjectFromEnv()

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckDNSManagedZoneDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccDNSManagedZone_forceDestroy(zoneSuffix),
Check: resource.ComposeTestCheckFunc(
testAccCheckManagedZoneCreateRRs(t, zoneSuffix, project),
),
},
},
})
}

func testAccCheckManagedZoneCreateRRs(t *testing.T, zoneSuffix string, project string) resource.TestCheckFunc {
return func(s *terraform.State) error {
config := googleProviderConfig(t)
zone := fmt.Sprintf("mzone-test-%s", zoneSuffix)
// Build the change
chg := &dns.Change{
Additions: []*dns.ResourceRecordSet{
{
Name: fmt.Sprintf("cname.%s.hashicorptest.com.", zoneSuffix),
Type: "CNAME",
Ttl: 300,
Rrdatas: []string{"foo.example.com."},
},
{
Name: fmt.Sprintf("a.%s.hashicorptest.com.", zoneSuffix),
Type: "A",
Ttl: 300,
Rrdatas: []string{"1.1.1.1"},
},
{
Name: fmt.Sprintf("nested.%s.hashicorptest.com.", zoneSuffix),
Type: "NS",
Ttl: 300,
Rrdatas: []string{"ns.hashicorp.services.", "ns2.hashicorp.services."},
},
},
}

chg, err := config.clientDns.Changes.Create(project, zone, chg).Do()
if err != nil {
return fmt.Errorf("Error creating DNS RecordSet: %s", err)
}

w := &DnsChangeWaiter{
Service: config.clientDns,
Change: chg,
Project: project,
ManagedZone: zone,
}
_, err = w.Conf().WaitForState()
if err != nil {
return fmt.Errorf("Error waiting for Google DNS change: %s", err)
}

return nil
}
}

func testAccDNSManagedZone_forceDestroy(suffix string) string {
return fmt.Sprintf(`
resource "google_dns_managed_zone" "foobar" {
name = "mzone-test-%s"
dns_name = "%s.hashicorptest.com."
labels = {
foo = "bar"
}
force_destroy = true
visibility = "public"
}
`, suffix, suffix)
}

func testAccDnsManagedZone_basic(suffix, description string) string {
return fmt.Sprintf(`
resource "google_dns_managed_zone" "foobar" {
Expand Down
2 changes: 1 addition & 1 deletion website/docs/r/dns_managed_zone.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ The following arguments are supported:
* `project` - (Optional) The ID of the project in which the resource belongs.
If it is not provided, the provider project is used.


Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* `force_destroy` - (Optional) Set this true to delete all records in the zone.
The `dnssec_config` block supports:

* `kind` -
Expand Down