github.com/andresvia/terraform@v0.6.15-0.20160412045437-d51c75946785/builtin/providers/azurerm/resource_arm_cdn_endpoint.go (about) 1 package azurerm 2 3 import ( 4 "bytes" 5 "fmt" 6 "log" 7 "net/http" 8 "strings" 9 "time" 10 11 "github.com/Azure/azure-sdk-for-go/arm/cdn" 12 "github.com/hashicorp/terraform/helper/hashcode" 13 "github.com/hashicorp/terraform/helper/resource" 14 "github.com/hashicorp/terraform/helper/schema" 15 ) 16 17 func resourceArmCdnEndpoint() *schema.Resource { 18 return &schema.Resource{ 19 Create: resourceArmCdnEndpointCreate, 20 Read: resourceArmCdnEndpointRead, 21 Update: resourceArmCdnEndpointUpdate, 22 Delete: resourceArmCdnEndpointDelete, 23 24 Schema: map[string]*schema.Schema{ 25 "name": &schema.Schema{ 26 Type: schema.TypeString, 27 Required: true, 28 ForceNew: true, 29 }, 30 31 "location": &schema.Schema{ 32 Type: schema.TypeString, 33 Required: true, 34 ForceNew: true, 35 StateFunc: azureRMNormalizeLocation, 36 }, 37 38 "resource_group_name": &schema.Schema{ 39 Type: schema.TypeString, 40 Required: true, 41 ForceNew: true, 42 }, 43 44 "profile_name": &schema.Schema{ 45 Type: schema.TypeString, 46 Required: true, 47 ForceNew: true, 48 }, 49 50 "origin_host_header": &schema.Schema{ 51 Type: schema.TypeString, 52 Optional: true, 53 Computed: true, 54 }, 55 56 "is_http_allowed": &schema.Schema{ 57 Type: schema.TypeBool, 58 Optional: true, 59 Default: true, 60 }, 61 62 "is_https_allowed": &schema.Schema{ 63 Type: schema.TypeBool, 64 Optional: true, 65 Default: true, 66 }, 67 68 "origin": &schema.Schema{ 69 Type: schema.TypeSet, 70 Required: true, 71 Elem: &schema.Resource{ 72 Schema: map[string]*schema.Schema{ 73 "name": &schema.Schema{ 74 Type: schema.TypeString, 75 Required: true, 76 }, 77 78 "host_name": &schema.Schema{ 79 Type: schema.TypeString, 80 Required: true, 81 }, 82 83 "http_port": &schema.Schema{ 84 Type: schema.TypeInt, 85 Optional: true, 86 Computed: true, 87 }, 88 89 "https_port": &schema.Schema{ 90 Type: schema.TypeInt, 91 Optional: true, 92 Computed: true, 93 }, 94 }, 95 }, 96 Set: resourceArmCdnEndpointOriginHash, 97 }, 98 99 "origin_path": &schema.Schema{ 100 Type: schema.TypeString, 101 Optional: true, 102 Computed: true, 103 }, 104 105 "querystring_caching_behaviour": &schema.Schema{ 106 Type: schema.TypeString, 107 Optional: true, 108 Default: "IgnoreQueryString", 109 ValidateFunc: validateCdnEndpointQuerystringCachingBehaviour, 110 }, 111 112 "content_types_to_compress": &schema.Schema{ 113 Type: schema.TypeSet, 114 Optional: true, 115 Computed: true, 116 Elem: &schema.Schema{Type: schema.TypeString}, 117 Set: schema.HashString, 118 }, 119 120 "is_compression_enabled": &schema.Schema{ 121 Type: schema.TypeBool, 122 Optional: true, 123 Default: false, 124 }, 125 126 "host_name": &schema.Schema{ 127 Type: schema.TypeString, 128 Computed: true, 129 }, 130 131 "tags": tagsSchema(), 132 }, 133 } 134 } 135 136 func resourceArmCdnEndpointCreate(d *schema.ResourceData, meta interface{}) error { 137 client := meta.(*ArmClient) 138 cdnEndpointsClient := client.cdnEndpointsClient 139 140 log.Printf("[INFO] preparing arguments for Azure ARM CDN EndPoint creation.") 141 142 name := d.Get("name").(string) 143 location := d.Get("location").(string) 144 resGroup := d.Get("resource_group_name").(string) 145 profileName := d.Get("profile_name").(string) 146 http_allowed := d.Get("is_http_allowed").(bool) 147 https_allowed := d.Get("is_https_allowed").(bool) 148 compression_enabled := d.Get("is_compression_enabled").(bool) 149 caching_behaviour := d.Get("querystring_caching_behaviour").(string) 150 tags := d.Get("tags").(map[string]interface{}) 151 152 properties := cdn.EndpointPropertiesCreateUpdateParameters{ 153 IsHTTPAllowed: &http_allowed, 154 IsHTTPSAllowed: &https_allowed, 155 IsCompressionEnabled: &compression_enabled, 156 QueryStringCachingBehavior: cdn.QueryStringCachingBehavior(caching_behaviour), 157 } 158 159 origins, originsErr := expandAzureRmCdnEndpointOrigins(d) 160 if originsErr != nil { 161 return fmt.Errorf("Error Building list of CDN Endpoint Origins: %s", originsErr) 162 } 163 if len(origins) > 0 { 164 properties.Origins = &origins 165 } 166 167 if v, ok := d.GetOk("origin_host_header"); ok { 168 host_header := v.(string) 169 properties.OriginHostHeader = &host_header 170 } 171 172 if v, ok := d.GetOk("origin_path"); ok { 173 origin_path := v.(string) 174 properties.OriginPath = &origin_path 175 } 176 177 if v, ok := d.GetOk("content_types_to_compress"); ok { 178 var content_types []string 179 ctypes := v.(*schema.Set).List() 180 for _, ct := range ctypes { 181 str := ct.(string) 182 content_types = append(content_types, str) 183 } 184 185 properties.ContentTypesToCompress = &content_types 186 } 187 188 cdnEndpoint := cdn.EndpointCreateParameters{ 189 Location: &location, 190 Properties: &properties, 191 Tags: expandTags(tags), 192 } 193 194 resp, err := cdnEndpointsClient.Create(name, cdnEndpoint, profileName, resGroup) 195 if err != nil { 196 return err 197 } 198 199 d.SetId(*resp.ID) 200 201 log.Printf("[DEBUG] Waiting for CDN Endpoint (%s) to become available", name) 202 stateConf := &resource.StateChangeConf{ 203 Pending: []string{"Accepted", "Updating", "Creating"}, 204 Target: []string{"Succeeded"}, 205 Refresh: cdnEndpointStateRefreshFunc(client, resGroup, profileName, name), 206 Timeout: 10 * time.Minute, 207 } 208 if _, err := stateConf.WaitForState(); err != nil { 209 return fmt.Errorf("Error waiting for CDN Endpoint (%s) to become available: %s", name, err) 210 } 211 212 return resourceArmCdnEndpointRead(d, meta) 213 } 214 215 func resourceArmCdnEndpointRead(d *schema.ResourceData, meta interface{}) error { 216 cdnEndpointsClient := meta.(*ArmClient).cdnEndpointsClient 217 218 id, err := parseAzureResourceID(d.Id()) 219 if err != nil { 220 return err 221 } 222 resGroup := id.ResourceGroup 223 name := id.Path["endpoints"] 224 profileName := id.Path["profiles"] 225 if profileName == "" { 226 profileName = id.Path["Profiles"] 227 } 228 log.Printf("[INFO] Trying to find the AzureRM CDN Endpoint %s (Profile: %s, RG: %s)", name, profileName, resGroup) 229 resp, err := cdnEndpointsClient.Get(name, profileName, resGroup) 230 if resp.StatusCode == http.StatusNotFound { 231 d.SetId("") 232 return nil 233 } 234 if err != nil { 235 return fmt.Errorf("Error making Read request on Azure CDN Endpoint %s: %s", name, err) 236 } 237 238 d.Set("name", resp.Name) 239 d.Set("host_name", resp.Properties.HostName) 240 d.Set("is_compression_enabled", resp.Properties.IsCompressionEnabled) 241 d.Set("is_http_allowed", resp.Properties.IsHTTPAllowed) 242 d.Set("is_https_allowed", resp.Properties.IsHTTPSAllowed) 243 d.Set("querystring_caching_behaviour", resp.Properties.QueryStringCachingBehavior) 244 if resp.Properties.OriginHostHeader != nil && *resp.Properties.OriginHostHeader != "" { 245 d.Set("origin_host_header", resp.Properties.OriginHostHeader) 246 } 247 if resp.Properties.OriginPath != nil && *resp.Properties.OriginPath != "" { 248 d.Set("origin_path", resp.Properties.OriginPath) 249 } 250 if resp.Properties.ContentTypesToCompress != nil && len(*resp.Properties.ContentTypesToCompress) > 0 { 251 d.Set("content_types_to_compress", flattenAzureRMCdnEndpointContentTypes(resp.Properties.ContentTypesToCompress)) 252 } 253 d.Set("origin", flattenAzureRMCdnEndpointOrigin(resp.Properties.Origins)) 254 255 flattenAndSetTags(d, resp.Tags) 256 257 return nil 258 } 259 260 func resourceArmCdnEndpointUpdate(d *schema.ResourceData, meta interface{}) error { 261 cdnEndpointsClient := meta.(*ArmClient).cdnEndpointsClient 262 263 if !d.HasChange("tags") { 264 return nil 265 } 266 267 name := d.Get("name").(string) 268 resGroup := d.Get("resource_group_name").(string) 269 profileName := d.Get("profile_name").(string) 270 http_allowed := d.Get("is_http_allowed").(bool) 271 https_allowed := d.Get("is_https_allowed").(bool) 272 compression_enabled := d.Get("is_compression_enabled").(bool) 273 caching_behaviour := d.Get("querystring_caching_behaviour").(string) 274 newTags := d.Get("tags").(map[string]interface{}) 275 276 properties := cdn.EndpointPropertiesCreateUpdateParameters{ 277 IsHTTPAllowed: &http_allowed, 278 IsHTTPSAllowed: &https_allowed, 279 IsCompressionEnabled: &compression_enabled, 280 QueryStringCachingBehavior: cdn.QueryStringCachingBehavior(caching_behaviour), 281 } 282 283 if d.HasChange("origin") { 284 origins, originsErr := expandAzureRmCdnEndpointOrigins(d) 285 if originsErr != nil { 286 return fmt.Errorf("Error Building list of CDN Endpoint Origins: %s", originsErr) 287 } 288 if len(origins) > 0 { 289 properties.Origins = &origins 290 } 291 } 292 293 if d.HasChange("origin_host_header") { 294 host_header := d.Get("origin_host_header").(string) 295 properties.OriginHostHeader = &host_header 296 } 297 298 if d.HasChange("origin_path") { 299 origin_path := d.Get("origin_path").(string) 300 properties.OriginPath = &origin_path 301 } 302 303 if d.HasChange("content_types_to_compress") { 304 var content_types []string 305 ctypes := d.Get("content_types_to_compress").(*schema.Set).List() 306 for _, ct := range ctypes { 307 str := ct.(string) 308 content_types = append(content_types, str) 309 } 310 311 properties.ContentTypesToCompress = &content_types 312 } 313 314 updateProps := cdn.EndpointUpdateParameters{ 315 Tags: expandTags(newTags), 316 Properties: &properties, 317 } 318 319 _, err := cdnEndpointsClient.Update(name, updateProps, profileName, resGroup) 320 if err != nil { 321 return fmt.Errorf("Error issuing Azure ARM update request to update CDN Endpoint %q: %s", name, err) 322 } 323 324 return resourceArmCdnEndpointRead(d, meta) 325 } 326 327 func resourceArmCdnEndpointDelete(d *schema.ResourceData, meta interface{}) error { 328 client := meta.(*ArmClient).cdnEndpointsClient 329 330 id, err := parseAzureResourceID(d.Id()) 331 if err != nil { 332 return err 333 } 334 resGroup := id.ResourceGroup 335 profileName := id.Path["profiles"] 336 if profileName == "" { 337 profileName = id.Path["Profiles"] 338 } 339 name := id.Path["endpoints"] 340 341 accResp, err := client.DeleteIfExists(name, profileName, resGroup) 342 if err != nil { 343 if accResp.StatusCode == http.StatusNotFound { 344 return nil 345 } 346 return fmt.Errorf("Error issuing AzureRM delete request for CDN Endpoint %q: %s", name, err) 347 } 348 _, err = pollIndefinitelyAsNeeded(client.Client, accResp.Response, http.StatusNotFound) 349 if err != nil { 350 return fmt.Errorf("Error polling for AzureRM delete request for CDN Endpoint %q: %s", name, err) 351 } 352 353 return err 354 } 355 356 func cdnEndpointStateRefreshFunc(client *ArmClient, resourceGroupName string, profileName string, name string) resource.StateRefreshFunc { 357 return func() (interface{}, string, error) { 358 res, err := client.cdnEndpointsClient.Get(name, profileName, resourceGroupName) 359 if err != nil { 360 return nil, "", fmt.Errorf("Error issuing read request in cdnEndpointStateRefreshFunc to Azure ARM for CDN Endpoint '%s' (RG: '%s'): %s", name, resourceGroupName, err) 361 } 362 return res, string(res.Properties.ProvisioningState), nil 363 } 364 } 365 366 func validateCdnEndpointQuerystringCachingBehaviour(v interface{}, k string) (ws []string, errors []error) { 367 value := strings.ToLower(v.(string)) 368 cachingTypes := map[string]bool{ 369 "ignorequerystring": true, 370 "bypasscaching": true, 371 "usequerystring": true, 372 } 373 374 if !cachingTypes[value] { 375 errors = append(errors, fmt.Errorf("CDN Endpoint querystringCachingBehaviours can only be IgnoreQueryString, BypassCaching or UseQueryString")) 376 } 377 return 378 } 379 380 func resourceArmCdnEndpointOriginHash(v interface{}) int { 381 var buf bytes.Buffer 382 m := v.(map[string]interface{}) 383 buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) 384 buf.WriteString(fmt.Sprintf("%s-", m["host_name"].(string))) 385 386 return hashcode.String(buf.String()) 387 } 388 389 func expandAzureRmCdnEndpointOrigins(d *schema.ResourceData) ([]cdn.DeepCreatedOrigin, error) { 390 configs := d.Get("origin").(*schema.Set).List() 391 origins := make([]cdn.DeepCreatedOrigin, 0, len(configs)) 392 393 for _, configRaw := range configs { 394 data := configRaw.(map[string]interface{}) 395 396 host_name := data["host_name"].(string) 397 398 properties := cdn.DeepCreatedOriginProperties{ 399 HostName: &host_name, 400 } 401 402 if v, ok := data["https_port"]; ok { 403 https_port := v.(int) 404 properties.HTTPSPort = &https_port 405 406 } 407 408 if v, ok := data["http_port"]; ok { 409 http_port := v.(int) 410 properties.HTTPPort = &http_port 411 } 412 413 name := data["name"].(string) 414 415 origin := cdn.DeepCreatedOrigin{ 416 Name: &name, 417 Properties: &properties, 418 } 419 420 origins = append(origins, origin) 421 } 422 423 return origins, nil 424 } 425 426 func flattenAzureRMCdnEndpointOrigin(list *[]cdn.DeepCreatedOrigin) []map[string]interface{} { 427 result := make([]map[string]interface{}, 0, len(*list)) 428 for _, i := range *list { 429 l := map[string]interface{}{ 430 "name": *i.Name, 431 "host_name": *i.Properties.HostName, 432 } 433 434 if i.Properties.HTTPPort != nil { 435 l["http_port"] = *i.Properties.HTTPPort 436 } 437 if i.Properties.HTTPSPort != nil { 438 l["https_port"] = *i.Properties.HTTPSPort 439 } 440 result = append(result, l) 441 } 442 return result 443 } 444 445 func flattenAzureRMCdnEndpointContentTypes(list *[]string) []interface{} { 446 vs := make([]interface{}, 0, len(*list)) 447 for _, v := range *list { 448 vs = append(vs, v) 449 } 450 return vs 451 }