Skip to content

Commit

Permalink
Merge pull request #200 from niuzhenguo/dns-ptr
Browse files Browse the repository at this point in the history
Add DNS Ptr record support
  • Loading branch information
niuzhenguo authored Sep 3, 2019
2 parents 91a668f + b472190 commit f96a9e0
Show file tree
Hide file tree
Showing 11 changed files with 609 additions and 6 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/hashicorp/errwrap v1.0.0
github.com/hashicorp/go-cleanhttp v0.5.0
github.com/hashicorp/terraform v0.12.0
github.com/huaweicloud/golangsdk v0.0.0-20190821064240-70d88a1c0686
github.com/huaweicloud/golangsdk v0.0.0-20190902122622-e395391e1f19
github.com/jen20/awspolicyequivalence v0.0.0-20170831201602-3d48364a137a
github.com/mitchellh/go-homedir v1.0.0
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ github.com/hashicorp/vault v0.10.4/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bA
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huaweicloud/golangsdk v0.0.0-20190821064240-70d88a1c0686 h1:hNz6V0LLPFPp+IcrMb9+tu6gZ2VC3IkphjgjQ1AFyOA=
github.com/huaweicloud/golangsdk v0.0.0-20190821064240-70d88a1c0686/go.mod h1:WQBcHRNX9shz3928lWEvstQJtAtYI7ks6XlgtRT9Tcw=
github.com/huaweicloud/golangsdk v0.0.0-20190902122622-e395391e1f19 h1:FUlribrcVGqGR4irupy34lbps5BPTJMurJ+kt/zxDmM=
github.com/huaweicloud/golangsdk v0.0.0-20190902122622-e395391e1f19/go.mod h1:WQBcHRNX9shz3928lWEvstQJtAtYI7ks6XlgtRT9Tcw=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/jen20/awspolicyequivalence v0.0.0-20170831201602-3d48364a137a h1:FyS/ubzBR5xJlnJGRTwe7GUHpJOR4ukYK3y+LFNffuA=
github.com/jen20/awspolicyequivalence v0.0.0-20170831201602-3d48364a137a/go.mod h1:uoIMjNxUfXi48Ci40IXkPRbghZ1vbti6v9LCbNqRgHY=
Expand Down
1 change: 1 addition & 0 deletions huaweicloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ func Provider() terraform.ResourceProvider {
"huaweicloud_compute_floatingip_v2": resourceComputeFloatingIPV2(),
"huaweicloud_compute_floatingip_associate_v2": resourceComputeFloatingIPAssociateV2(),
"huaweicloud_compute_volume_attach_v2": resourceComputeVolumeAttachV2(),
"huaweicloud_dns_ptrrecord_v2": resourceDNSPtrRecordV2(),
"huaweicloud_dns_recordset_v2": resourceDNSRecordSetV2(),
"huaweicloud_dns_zone_v2": resourceDNSZoneV2(),
"huaweicloud_dcs_instance_v1": resourceDcsInstanceV1(),
Expand Down
264 changes: 264 additions & 0 deletions huaweicloud/resource_huaweicloud_dns_ptrrecord_v2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
package huaweicloud

import (
"fmt"
"log"
"strings"
"time"

"github.com/huaweicloud/golangsdk"
"github.com/huaweicloud/golangsdk/openstack/dns/v2/ptrrecords"

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)

func resourceDNSPtrRecordV2() *schema.Resource {
return &schema.Resource{
Create: resourceDNSPtrRecordV2Create,
Read: resourceDNSPtrRecordV2Read,
Update: resourceDNSPtrRecordV2Update,
Delete: resourceDNSPtrRecordV2Delete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(10 * time.Minute),
Update: schema.DefaultTimeout(10 * time.Minute),
Delete: schema.DefaultTimeout(10 * time.Minute),
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: false,
},
"description": {
Type: schema.TypeString,
Optional: true,
ForceNew: false,
},
"floatingip_id": {
Type: schema.TypeString,
Required: true,
ForceNew: false,
},
"ttl": {
Type: schema.TypeInt,
Optional: true,
ForceNew: false,
ValidateFunc: resourceValidateTTL,
},
"tags": {
Type: schema.TypeMap,
Optional: true,
ForceNew: false,
ValidateFunc: validateECSTagValue,
},
"address": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func resourceDNSPtrRecordV2Create(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
region := GetRegion(d, config)
dnsClient, err := config.dnsV2Client(region)
if err != nil {
return fmt.Errorf("Error creating HuaweiCloud DNS client: %s", err)
}

tagmap := d.Get("tags").(map[string]interface{})
taglist := []ptrrecords.Tag{}
for k, v := range tagmap {
tag := ptrrecords.Tag{
Key: k,
Value: v.(string),
}
taglist = append(taglist, tag)
}

createOpts := ptrrecords.CreateOpts{
PtrName: d.Get("name").(string),
Description: d.Get("description").(string),
TTL: d.Get("ttl").(int),
Tags: taglist,
}

log.Printf("[DEBUG] Create Options: %#v", createOpts)
fip_id := d.Get("floatingip_id").(string)
n, err := ptrrecords.Create(dnsClient, region, fip_id, createOpts).Extract()
if err != nil {
return fmt.Errorf("Error creating HuaweiCloud DNS PTR record: %s", err)
}

log.Printf("[DEBUG] Waiting for DNS PTR record (%s) to become available", n.ID)
stateConf := &resource.StateChangeConf{
Target: []string{"ACTIVE"},
Pending: []string{"PENDING_CREATE"},
Refresh: waitForDNSPtrRecord(dnsClient, n.ID),
Timeout: d.Timeout(schema.TimeoutCreate),
Delay: 5 * time.Second,
MinTimeout: 3 * time.Second,
}

_, err = stateConf.WaitForState()

if err != nil {
return fmt.Errorf(
"Error waiting for PTR record (%s) to become ACTIVE for creation: %s",
n.ID, err)
}
d.SetId(n.ID)

log.Printf("[DEBUG] Created HuaweiCloud DNS PTR record %s: %#v", n.ID, n)
return resourceDNSPtrRecordV2Read(d, meta)
}

func resourceDNSPtrRecordV2Read(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
dnsClient, err := config.dnsV2Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating HuaweiCloud DNS client: %s", err)
}

n, err := ptrrecords.Get(dnsClient, d.Id()).Extract()
if err != nil {
return CheckDeleted(d, err, "ptr_record")
}

log.Printf("[DEBUG] Retrieved PTR record %s: %#v", d.Id(), n)

// Obtain relevant info from parsing the ID
fipID, err := parseDNSV2PtrRecordID(d.Id())
if err != nil {
return err
}

d.Set("name", n.PtrName)
d.Set("description", n.Description)
d.Set("floatingip_id", fipID)
d.Set("ttl", n.TTL)
d.Set("address", n.Address)

return nil
}

func resourceDNSPtrRecordV2Update(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
region := GetRegion(d, config)
dnsClient, err := config.dnsV2Client(region)
if err != nil {
return fmt.Errorf("Error creating HuaweiCloud DNS client: %s", err)
}

tagmap := d.Get("tags").(map[string]interface{})
taglist := []ptrrecords.Tag{}
for k, v := range tagmap {
tag := ptrrecords.Tag{
Key: k,
Value: v.(string),
}
taglist = append(taglist, tag)
}

createOpts := ptrrecords.CreateOpts{
PtrName: d.Get("name").(string),
Description: d.Get("description").(string),
TTL: d.Get("ttl").(int),
Tags: taglist,
}

log.Printf("[DEBUG] Update Options: %#v", createOpts)
fip_id := d.Get("floatingip_id").(string)
n, err := ptrrecords.Create(dnsClient, region, fip_id, createOpts).Extract()
if err != nil {
return fmt.Errorf("Error updating HuaweiCloud DNS PTR record: %s", err)
}

log.Printf("[DEBUG] Waiting for DNS PTR record (%s) to become available", n.ID)
stateConf := &resource.StateChangeConf{
Target: []string{"ACTIVE"},
Pending: []string{"PENDING_CREATE"},
Refresh: waitForDNSPtrRecord(dnsClient, n.ID),
Timeout: d.Timeout(schema.TimeoutCreate),
Delay: 5 * time.Second,
MinTimeout: 3 * time.Second,
}

_, err = stateConf.WaitForState()

if err != nil {
return fmt.Errorf(
"Error waiting for PTR record (%s) to become ACTIVE for update: %s",
n.ID, err)
}

log.Printf("[DEBUG] Updated HuaweiCloud DNS PTR record %s: %#v", n.ID, n)
return resourceDNSPtrRecordV2Read(d, meta)

}

func resourceDNSPtrRecordV2Delete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
dnsClient, err := config.dnsV2Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating HuaweiCloud DNS client: %s", err)
}

err = ptrrecords.Delete(dnsClient, d.Id()).ExtractErr()
if err != nil {
return fmt.Errorf("Error deleting HuaweiCloud DNS PTR record: %s", err)
}

log.Printf("[DEBUG] Waiting for DNS PTR record (%s) to be deleted", d.Id())
stateConf := &resource.StateChangeConf{
Target: []string{"DELETED"},
Pending: []string{"ACTIVE", "PENDING_DELETE", "ERROR"},
Refresh: waitForDNSPtrRecord(dnsClient, d.Id()),
Timeout: d.Timeout(schema.TimeoutDelete),
Delay: 5 * time.Second,
MinTimeout: 3 * time.Second,
}

_, err = stateConf.WaitForState()
if err != nil {
return fmt.Errorf(
"Error waiting for PTR record (%s) to become DELETED for deletion: %s",
d.Id(), err)
}

d.SetId("")
return nil
}

func waitForDNSPtrRecord(dnsClient *golangsdk.ServiceClient, id string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
ptrrecord, err := ptrrecords.Get(dnsClient, id).Extract()
if err != nil {
if _, ok := err.(golangsdk.ErrDefault404); ok {
return ptrrecord, "DELETED", nil
}

return nil, "", err
}

log.Printf("[DEBUG] HuaweiCloud DNS PTR record (%s) current status: %s", ptrrecord.ID, ptrrecord.Status)
return ptrrecord, ptrrecord.Status, nil
}
}

func parseDNSV2PtrRecordID(id string) (string, error) {
idParts := strings.Split(id, ":")
if len(idParts) != 2 {
return "", fmt.Errorf("Unable to determine DNS PTR record ID from raw ID: %s", id)
}

fipID := idParts[1]
return fipID, nil
}
Loading

0 comments on commit f96a9e0

Please sign in to comment.