provider/openstack: dns zone v2 updates and docs

This commit is contained in:
Joe Topjian 2017-05-21 22:39:52 +00:00
parent 5792b9fe76
commit e0b5f4f833
6 changed files with 257 additions and 36 deletions

View File

@ -1,12 +1,15 @@
package openstack
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccDNSV2Zone_importBasic(t *testing.T) {
var zoneName = fmt.Sprintf("ACPTTEST%s.com.", acctest.RandString(5))
resourceName := "openstack_dns_zone_v2.zone_1"
resource.Test(t, resource.TestCase{
@ -15,7 +18,7 @@ func TestAccDNSV2Zone_importBasic(t *testing.T) {
CheckDestroy: testAccCheckDNSV2ZoneDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccDNSV2Zone_basic,
Config: testAccDNSV2Zone_basic(zoneName),
},
resource.TestStep{

View File

@ -3,10 +3,12 @@ package openstack
import (
"fmt"
"log"
"strconv"
"time"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack/dns/v2/zones"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)
@ -22,6 +24,7 @@ func resourceDNSZoneV2() *schema.Resource {
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(10 * time.Minute),
Update: schema.DefaultTimeout(10 * time.Minute),
Delete: schema.DefaultTimeout(10 * time.Minute),
},
@ -43,9 +46,11 @@ func resourceDNSZoneV2() *schema.Resource {
ForceNew: false,
},
"type": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ValidateFunc: resourceDNSZoneV2ValidType,
},
"attributes": &schema.Schema{
Type: schema.TypeMap,
@ -55,6 +60,7 @@ func resourceDNSZoneV2() *schema.Resource {
"ttl": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
Computed: true,
ForceNew: false,
},
"description": &schema.Schema{
@ -114,10 +120,22 @@ func resourceDNSZoneV2Create(d *schema.ResourceData, meta interface{}) error {
if err != nil {
return fmt.Errorf("Error creating OpenStack DNS zone: %s", err)
}
log.Printf("[INFO] Zone ID: %s", n.ID)
log.Printf("[DEBUG] Waiting for DNS Zone (%s) to become available", n.ID)
stateConf := &resource.StateChangeConf{
Target: []string{"ACTIVE"},
Pending: []string{"PENDING"},
Refresh: waitForDNSZone(dnsClient, n.ID),
Timeout: d.Timeout(schema.TimeoutCreate),
Delay: 5 * time.Second,
MinTimeout: 3 * time.Second,
}
_, err = stateConf.WaitForState()
d.SetId(n.ID)
log.Printf("[DEBUG] Created OpenStack DNS Zone %s: %#v", n.ID, n)
return resourceDNSZoneV2Read(d, meta)
}
@ -133,12 +151,12 @@ func resourceDNSZoneV2Read(d *schema.ResourceData, meta interface{}) error {
return CheckDeleted(d, err, "zone")
}
log.Printf("[DEBUG] Retrieved Zone %s: %+v", d.Id(), n)
log.Printf("[DEBUG] Retrieved Zone %s: %#v", d.Id(), n)
d.Set("name", n.Name)
d.Set("email", n.Email)
d.Set("description", n.Description)
d.Set("ttl", strconv.Itoa(n.TTL))
d.Set("ttl", n.TTL)
d.Set("type", n.Type)
d.Set("attributes", n.Attributes)
d.Set("masters", n.Masters)
@ -168,13 +186,25 @@ func resourceDNSZoneV2Update(d *schema.ResourceData, meta interface{}) error {
updateOpts.Description = d.Get("description").(string)
}
log.Printf("[DEBUG] Updating Zone %s with options: %+v", d.Id(), updateOpts)
log.Printf("[DEBUG] Updating Zone %s with options: %#v", d.Id(), updateOpts)
_, err = zones.Update(dnsClient, d.Id(), updateOpts).Extract()
if err != nil {
return fmt.Errorf("Error updating OpenStack DNS Zone: %s", err)
}
log.Printf("[DEBUG] Waiting for DNS Zone (%s) to update", d.Id())
stateConf := &resource.StateChangeConf{
Target: []string{"ACTIVE"},
Pending: []string{"PENDING"},
Refresh: waitForDNSZone(dnsClient, d.Id()),
Timeout: d.Timeout(schema.TimeoutUpdate),
Delay: 5 * time.Second,
MinTimeout: 3 * time.Second,
}
_, err = stateConf.WaitForState()
return resourceDNSZoneV2Read(d, meta)
}
@ -190,6 +220,52 @@ func resourceDNSZoneV2Delete(d *schema.ResourceData, meta interface{}) error {
return fmt.Errorf("Error deleting OpenStack DNS Zone: %s", err)
}
log.Printf("[DEBUG] Waiting for DNS Zone (%s) to become available", d.Id())
stateConf := &resource.StateChangeConf{
Target: []string{"DELETED"},
Pending: []string{"ACTIVE", "PENDING"},
Refresh: waitForDNSZone(dnsClient, d.Id()),
Timeout: d.Timeout(schema.TimeoutDelete),
Delay: 5 * time.Second,
MinTimeout: 3 * time.Second,
}
_, err = stateConf.WaitForState()
d.SetId("")
return nil
}
func resourceDNSZoneV2ValidType(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
validTypes := []string{
"PRIMARY",
"SECONDARY",
}
for _, v := range validTypes {
if value == v {
return
}
}
err := fmt.Errorf("%s must be one of %s", k, validTypes)
errors = append(errors, err)
return
}
func waitForDNSZone(dnsClient *gophercloud.ServiceClient, zoneId string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
zone, err := zones.Get(dnsClient, zoneId).Extract()
if err != nil {
if _, ok := err.(gophercloud.ErrDefault404); ok {
return zone, "DELETED", nil
}
return nil, "", err
}
log.Printf("[DEBUG] OpenStack DNS Zone (%s) current status: %s", zone.ID, zone.Status)
return zone, zone.Status, nil
}
}

View File

@ -3,8 +3,10 @@ package openstack
import (
"fmt"
"os"
"regexp"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
@ -13,6 +15,7 @@ import (
func TestAccDNSV2Zone_basic(t *testing.T) {
var zone zones.Zone
var zoneName = fmt.Sprintf("ACPTTEST%s.com.", acctest.RandString(5))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheckDNSZoneV2(t) },
@ -20,17 +23,44 @@ func TestAccDNSV2Zone_basic(t *testing.T) {
CheckDestroy: testAccCheckDNSV2ZoneDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccDNSV2Zone_basic,
Config: testAccDNSV2Zone_basic(zoneName),
Check: resource.ComposeTestCheckFunc(
testAccCheckDNSV2ZoneExists("openstack_dns_zone_v2.zone_1", &zone),
resource.TestCheckResourceAttr(
"openstack_dns_zone_v2.zone_1", "description", "a zone"),
),
},
resource.TestStep{
Config: testAccDNSV2Zone_update,
Config: testAccDNSV2Zone_update(zoneName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("openstack_dns_zone_v2.zone_1", "name", "example.com"),
resource.TestCheckResourceAttr("openstack_dns_zone_v2.zone_1", "name", zoneName),
resource.TestCheckResourceAttr("openstack_dns_zone_v2.zone_1", "email", "email2@example.com"),
resource.TestCheckResourceAttr("openstack_dns_zone_v2.zone_1", "ttl", "6000"),
resource.TestCheckResourceAttr("openstack_dns_zone_v2.zone_1", "type", "PRIMARY"),
resource.TestCheckResourceAttr(
"openstack_dns_zone_v2.zone_1", "description", "an updated zone"),
),
},
},
})
}
func TestAccDNSV2Zone_readTTL(t *testing.T) {
var zone zones.Zone
var zoneName = fmt.Sprintf("ACPTTEST%s.com.", acctest.RandString(5))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheckDNSZoneV2(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckDNSV2ZoneDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccDNSV2Zone_readTTL(zoneName),
Check: resource.ComposeTestCheckFunc(
testAccCheckDNSV2ZoneExists("openstack_dns_zone_v2.zone_1", &zone),
resource.TestCheckResourceAttr("openstack_dns_zone_v2.zone_1", "type", "PRIMARY"),
resource.TestMatchResourceAttr(
"openstack_dns_zone_v2.zone_1", "ttl", regexp.MustCompile("^[0-9]+$")),
),
},
},
@ -39,6 +69,7 @@ func TestAccDNSV2Zone_basic(t *testing.T) {
func TestAccDNSV2Zone_timeout(t *testing.T) {
var zone zones.Zone
var zoneName = fmt.Sprintf("ACPTTEST%s.com.", acctest.RandString(5))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheckDNSZoneV2(t) },
@ -46,7 +77,7 @@ func TestAccDNSV2Zone_timeout(t *testing.T) {
CheckDestroy: testAccCheckDNSV2ZoneDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccDNSV2Zone_timeout,
Config: testAccDNSV2Zone_timeout(zoneName),
Check: resource.ComposeTestCheckFunc(
testAccCheckDNSV2ZoneExists("openstack_dns_zone_v2.zone_1", &zone),
),
@ -115,31 +146,51 @@ func testAccPreCheckDNSZoneV2(t *testing.T) {
}
}
const testAccDNSV2Zone_basic = `
resource "openstack_dns_zone_v2" "zone_1" {
name = "example.com."
email = "email1@example.com"
ttl = 3000
func testAccDNSV2Zone_basic(zoneName string) string {
return fmt.Sprintf(`
resource "openstack_dns_zone_v2" "zone_1" {
name = "%s"
email = "email1@example.com"
description = "a zone"
ttl = 3000
type = "PRIMARY"
}
`, zoneName)
}
`
const testAccDNSV2Zone_update = `
resource "openstack_dns_zone_v2" "zone_1" {
name = "example.com."
email = "email2@example.com"
ttl = 6000
func testAccDNSV2Zone_update(zoneName string) string {
return fmt.Sprintf(`
resource "openstack_dns_zone_v2" "zone_1" {
name = "%s"
email = "email2@example.com"
description = "an updated zone"
ttl = 6000
type = "PRIMARY"
}
`, zoneName)
}
`
const testAccDNSV2Zone_timeout = `
resource "openstack_dns_zone_v2" "zone_1" {
name = "example.com."
email = "email@example.com"
ttl = 3000
timeouts {
create = "5m"
delete = "5m"
}
func testAccDNSV2Zone_readTTL(zoneName string) string {
return fmt.Sprintf(`
resource "openstack_dns_zone_v2" "zone_1" {
name = "%s"
email = "email1@example.com"
}
`, zoneName)
}
func testAccDNSV2Zone_timeout(zoneName string) string {
return fmt.Sprintf(`
resource "openstack_dns_zone_v2" "zone_1" {
name = "%s"
email = "email@example.com"
ttl = 3000
timeouts {
create = "5m"
update = "5m"
delete = "5m"
}
}
`, zoneName)
}
`

View File

@ -306,6 +306,10 @@ func (opts ZoneCreateOpts) ToZoneCreateMap() (map[string]interface{}, error) {
}
if m, ok := b[""].(map[string]interface{}); ok {
if opts.TTL > 0 {
m["ttl"] = opts.TTL
}
return m, nil
}

View File

@ -0,0 +1,78 @@
---
layout: "openstack"
page_title: "OpenStack: openstack_dns_zone_v2"
sidebar_current: "docs-openstack-resource-dns-zone-v2"
description: |-
Manages a DNS zone in the OpenStack DNS Service
---
# openstack\_dns\_zone_v2
Manages a DNS zone in the OpenStack DNS Service.
## Example Usage
### Automatically detect the correct network
```hcl
resource "openstack_dns_zone_v2" "example.com" {
name = "example.com."
email = "jdoe@example.com"
description = "An example zone"
ttl = 3000
type = "PRIMARY"
}
```
## Argument Reference
The following arguments are supported:
* `region` - (Required) The region in which to obtain the V2 Compute client.
Keypairs are associated with accounts, but a Compute client is needed to
create one. If omitted, the `OS_REGION_NAME` environment variable is used.
Changing this creates a new DNS zone.
* `name` - (Required) The name of the zone. Note the `.` at the end of the name.
Changing this creates a new DNS zone.
* `email` - (Optional) The email contact for the zone record.
* `type` - (Optional) The type of zone. Can either be `PRIMARY` or `SECONDARY`.
Changing this creates a new zone.
* `attributes` - (Optional) Attributes for the DNS Service scheduler.
Changing this creates a new zone.
* `ttl` - (Optional) The time to live (TTL) of the zone.
* `description` - (Optional) A description of the zone.
* `masters` - (Optional) An array of master DNS servers. For when `type` is
`SECONDARY`.
* `value_specs` - (Optional) Map of additional options. Changing this creates a
new zone.
## Attributes Reference
The following attributes are exported:
* `region` - See Argument Reference above.
* `name` - See Argument Reference above.
* `email` - See Argument Reference above.
* `type` - See Argument Reference above.
* `attributes` - See Argument Reference above.
* `ttl` - See Argument Reference above.
* `description` - See Argument Reference above.
* `masters` - See Argument Reference above.
* `value_specs` - See Argument Reference above.
## Import
This resource can be imported by specifying all three arguments, separated
by a forward slash:
```
$ terraform import openstack_dns_zone_v2.zone_1 <zone_id>
```

View File

@ -64,6 +64,15 @@
</ul>
</li>
<li<%= sidebar_current("docs-openstack-resource-dns") %>>
<a href="#">DNS Resources</a>
<ul class="nav nav-visible">
<li<%= sidebar_current("docs-openstack-resource-dns-zone-v2") %>>
<a href="/docs/providers/openstack/r/dns_zone_v2.html">openstack_dns_zone_v2</a>
</li>
</ul>
</li>
<li<%= sidebar_current("docs-openstack-resource-images") %>>
<a href="#">Images Resources</a>
<ul class="nav nav-visible">