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 }