github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/openstack/resource_openstack_dns_zone_v2.go (about)

     1  package openstack
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"time"
     7  
     8  	"github.com/gophercloud/gophercloud"
     9  	"github.com/gophercloud/gophercloud/openstack/dns/v2/zones"
    10  
    11  	"github.com/hashicorp/terraform/helper/resource"
    12  	"github.com/hashicorp/terraform/helper/schema"
    13  )
    14  
    15  func resourceDNSZoneV2() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: resourceDNSZoneV2Create,
    18  		Read:   resourceDNSZoneV2Read,
    19  		Update: resourceDNSZoneV2Update,
    20  		Delete: resourceDNSZoneV2Delete,
    21  		Importer: &schema.ResourceImporter{
    22  			State: schema.ImportStatePassthrough,
    23  		},
    24  
    25  		Timeouts: &schema.ResourceTimeout{
    26  			Create: schema.DefaultTimeout(10 * time.Minute),
    27  			Update: schema.DefaultTimeout(10 * time.Minute),
    28  			Delete: schema.DefaultTimeout(10 * time.Minute),
    29  		},
    30  
    31  		Schema: map[string]*schema.Schema{
    32  			"region": &schema.Schema{
    33  				Type:        schema.TypeString,
    34  				Required:    true,
    35  				ForceNew:    true,
    36  				DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""),
    37  			},
    38  			"name": &schema.Schema{
    39  				Type:     schema.TypeString,
    40  				Required: true,
    41  				ForceNew: true,
    42  			},
    43  			"email": &schema.Schema{
    44  				Type:     schema.TypeString,
    45  				Optional: true,
    46  				ForceNew: false,
    47  			},
    48  			"type": &schema.Schema{
    49  				Type:         schema.TypeString,
    50  				Optional:     true,
    51  				Computed:     true,
    52  				ForceNew:     true,
    53  				ValidateFunc: resourceDNSZoneV2ValidType,
    54  			},
    55  			"attributes": &schema.Schema{
    56  				Type:     schema.TypeMap,
    57  				Optional: true,
    58  				ForceNew: true,
    59  			},
    60  			"ttl": &schema.Schema{
    61  				Type:     schema.TypeInt,
    62  				Optional: true,
    63  				Computed: true,
    64  				ForceNew: false,
    65  			},
    66  			"description": &schema.Schema{
    67  				Type:     schema.TypeString,
    68  				Optional: true,
    69  				ForceNew: false,
    70  			},
    71  			"masters": &schema.Schema{
    72  				Type:     schema.TypeSet,
    73  				Optional: true,
    74  				ForceNew: false,
    75  				Elem:     &schema.Schema{Type: schema.TypeString},
    76  			},
    77  			"value_specs": &schema.Schema{
    78  				Type:     schema.TypeMap,
    79  				Optional: true,
    80  				ForceNew: true,
    81  			},
    82  		},
    83  	}
    84  }
    85  
    86  func resourceDNSZoneV2Create(d *schema.ResourceData, meta interface{}) error {
    87  	config := meta.(*Config)
    88  	dnsClient, err := config.dnsV2Client(GetRegion(d))
    89  	if err != nil {
    90  		return fmt.Errorf("Error creating OpenStack DNS client: %s", err)
    91  	}
    92  
    93  	mastersraw := d.Get("masters").(*schema.Set).List()
    94  	masters := make([]string, len(mastersraw))
    95  	for i, masterraw := range mastersraw {
    96  		masters[i] = masterraw.(string)
    97  	}
    98  
    99  	attrsraw := d.Get("attributes").(map[string]interface{})
   100  	attrs := make(map[string]string, len(attrsraw))
   101  	for k, v := range attrsraw {
   102  		attrs[k] = v.(string)
   103  	}
   104  
   105  	createOpts := ZoneCreateOpts{
   106  		zones.CreateOpts{
   107  			Name:        d.Get("name").(string),
   108  			Type:        d.Get("type").(string),
   109  			Attributes:  attrs,
   110  			TTL:         d.Get("ttl").(int),
   111  			Email:       d.Get("email").(string),
   112  			Description: d.Get("description").(string),
   113  			Masters:     masters,
   114  		},
   115  		MapValueSpecs(d),
   116  	}
   117  
   118  	log.Printf("[DEBUG] Create Options: %#v", createOpts)
   119  	n, err := zones.Create(dnsClient, createOpts).Extract()
   120  	if err != nil {
   121  		return fmt.Errorf("Error creating OpenStack DNS zone: %s", err)
   122  	}
   123  
   124  	log.Printf("[DEBUG] Waiting for DNS Zone (%s) to become available", n.ID)
   125  	stateConf := &resource.StateChangeConf{
   126  		Target:     []string{"ACTIVE"},
   127  		Pending:    []string{"PENDING"},
   128  		Refresh:    waitForDNSZone(dnsClient, n.ID),
   129  		Timeout:    d.Timeout(schema.TimeoutCreate),
   130  		Delay:      5 * time.Second,
   131  		MinTimeout: 3 * time.Second,
   132  	}
   133  
   134  	_, err = stateConf.WaitForState()
   135  
   136  	d.SetId(n.ID)
   137  
   138  	log.Printf("[DEBUG] Created OpenStack DNS Zone %s: %#v", n.ID, n)
   139  	return resourceDNSZoneV2Read(d, meta)
   140  }
   141  
   142  func resourceDNSZoneV2Read(d *schema.ResourceData, meta interface{}) error {
   143  	config := meta.(*Config)
   144  	dnsClient, err := config.dnsV2Client(GetRegion(d))
   145  	if err != nil {
   146  		return fmt.Errorf("Error creating OpenStack DNS client: %s", err)
   147  	}
   148  
   149  	n, err := zones.Get(dnsClient, d.Id()).Extract()
   150  	if err != nil {
   151  		return CheckDeleted(d, err, "zone")
   152  	}
   153  
   154  	log.Printf("[DEBUG] Retrieved Zone %s: %#v", d.Id(), n)
   155  
   156  	d.Set("name", n.Name)
   157  	d.Set("email", n.Email)
   158  	d.Set("description", n.Description)
   159  	d.Set("ttl", n.TTL)
   160  	d.Set("type", n.Type)
   161  	d.Set("attributes", n.Attributes)
   162  	d.Set("masters", n.Masters)
   163  	d.Set("region", GetRegion(d))
   164  
   165  	return nil
   166  }
   167  
   168  func resourceDNSZoneV2Update(d *schema.ResourceData, meta interface{}) error {
   169  	config := meta.(*Config)
   170  	dnsClient, err := config.dnsV2Client(GetRegion(d))
   171  	if err != nil {
   172  		return fmt.Errorf("Error creating OpenStack DNS client: %s", err)
   173  	}
   174  
   175  	var updateOpts zones.UpdateOpts
   176  	if d.HasChange("email") {
   177  		updateOpts.Email = d.Get("email").(string)
   178  	}
   179  	if d.HasChange("ttl") {
   180  		updateOpts.TTL = d.Get("ttl").(int)
   181  	}
   182  	if d.HasChange("masters") {
   183  		mastersraw := d.Get("masters").(*schema.Set).List()
   184  		masters := make([]string, len(mastersraw))
   185  		for i, masterraw := range mastersraw {
   186  			masters[i] = masterraw.(string)
   187  		}
   188  		updateOpts.Masters = masters
   189  	}
   190  	if d.HasChange("description") {
   191  		updateOpts.Description = d.Get("description").(string)
   192  	}
   193  
   194  	log.Printf("[DEBUG] Updating Zone %s with options: %#v", d.Id(), updateOpts)
   195  
   196  	_, err = zones.Update(dnsClient, d.Id(), updateOpts).Extract()
   197  	if err != nil {
   198  		return fmt.Errorf("Error updating OpenStack DNS Zone: %s", err)
   199  	}
   200  
   201  	log.Printf("[DEBUG] Waiting for DNS Zone (%s) to update", d.Id())
   202  	stateConf := &resource.StateChangeConf{
   203  		Target:     []string{"ACTIVE"},
   204  		Pending:    []string{"PENDING"},
   205  		Refresh:    waitForDNSZone(dnsClient, d.Id()),
   206  		Timeout:    d.Timeout(schema.TimeoutUpdate),
   207  		Delay:      5 * time.Second,
   208  		MinTimeout: 3 * time.Second,
   209  	}
   210  
   211  	_, err = stateConf.WaitForState()
   212  
   213  	return resourceDNSZoneV2Read(d, meta)
   214  }
   215  
   216  func resourceDNSZoneV2Delete(d *schema.ResourceData, meta interface{}) error {
   217  	config := meta.(*Config)
   218  	dnsClient, err := config.dnsV2Client(GetRegion(d))
   219  	if err != nil {
   220  		return fmt.Errorf("Error creating OpenStack DNS client: %s", err)
   221  	}
   222  
   223  	_, err = zones.Delete(dnsClient, d.Id()).Extract()
   224  	if err != nil {
   225  		return fmt.Errorf("Error deleting OpenStack DNS Zone: %s", err)
   226  	}
   227  
   228  	log.Printf("[DEBUG] Waiting for DNS Zone (%s) to become available", d.Id())
   229  	stateConf := &resource.StateChangeConf{
   230  		Target:     []string{"DELETED"},
   231  		Pending:    []string{"ACTIVE", "PENDING"},
   232  		Refresh:    waitForDNSZone(dnsClient, d.Id()),
   233  		Timeout:    d.Timeout(schema.TimeoutDelete),
   234  		Delay:      5 * time.Second,
   235  		MinTimeout: 3 * time.Second,
   236  	}
   237  
   238  	_, err = stateConf.WaitForState()
   239  
   240  	d.SetId("")
   241  	return nil
   242  }
   243  
   244  func resourceDNSZoneV2ValidType(v interface{}, k string) (ws []string, errors []error) {
   245  	value := v.(string)
   246  	validTypes := []string{
   247  		"PRIMARY",
   248  		"SECONDARY",
   249  	}
   250  
   251  	for _, v := range validTypes {
   252  		if value == v {
   253  			return
   254  		}
   255  	}
   256  
   257  	err := fmt.Errorf("%s must be one of %s", k, validTypes)
   258  	errors = append(errors, err)
   259  	return
   260  }
   261  
   262  func waitForDNSZone(dnsClient *gophercloud.ServiceClient, zoneId string) resource.StateRefreshFunc {
   263  	return func() (interface{}, string, error) {
   264  		zone, err := zones.Get(dnsClient, zoneId).Extract()
   265  		if err != nil {
   266  			if _, ok := err.(gophercloud.ErrDefault404); ok {
   267  				return zone, "DELETED", nil
   268  			}
   269  
   270  			return nil, "", err
   271  		}
   272  
   273  		log.Printf("[DEBUG] OpenStack DNS Zone (%s) current status: %s", zone.ID, zone.Status)
   274  		return zone, zone.Status, nil
   275  	}
   276  }