github.com/ottenhoff/terraform@v0.7.0-rc1.0.20160607213102-ac2d195cc560/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 10 "github.com/Azure/azure-sdk-for-go/arm/cdn" 11 "github.com/hashicorp/terraform/helper/hashcode" 12 "github.com/hashicorp/terraform/helper/schema" 13 ) 14 15 func resourceArmCdnEndpoint() *schema.Resource { 16 return &schema.Resource{ 17 Create: resourceArmCdnEndpointCreate, 18 Read: resourceArmCdnEndpointRead, 19 Update: resourceArmCdnEndpointUpdate, 20 Delete: resourceArmCdnEndpointDelete, 21 22 Schema: map[string]*schema.Schema{ 23 "name": { 24 Type: schema.TypeString, 25 Required: true, 26 ForceNew: true, 27 }, 28 29 "location": { 30 Type: schema.TypeString, 31 Required: true, 32 ForceNew: true, 33 StateFunc: azureRMNormalizeLocation, 34 }, 35 36 "resource_group_name": { 37 Type: schema.TypeString, 38 Required: true, 39 ForceNew: true, 40 }, 41 42 "profile_name": { 43 Type: schema.TypeString, 44 Required: true, 45 ForceNew: true, 46 }, 47 48 "origin_host_header": { 49 Type: schema.TypeString, 50 Optional: true, 51 Computed: true, 52 }, 53 54 "is_http_allowed": { 55 Type: schema.TypeBool, 56 Optional: true, 57 Default: true, 58 }, 59 60 "is_https_allowed": { 61 Type: schema.TypeBool, 62 Optional: true, 63 Default: true, 64 }, 65 66 "origin": { 67 Type: schema.TypeSet, 68 Required: true, 69 Elem: &schema.Resource{ 70 Schema: map[string]*schema.Schema{ 71 "name": { 72 Type: schema.TypeString, 73 Required: true, 74 }, 75 76 "host_name": { 77 Type: schema.TypeString, 78 Required: true, 79 }, 80 81 "http_port": { 82 Type: schema.TypeInt, 83 Optional: true, 84 Computed: true, 85 }, 86 87 "https_port": { 88 Type: schema.TypeInt, 89 Optional: true, 90 Computed: true, 91 }, 92 }, 93 }, 94 Set: resourceArmCdnEndpointOriginHash, 95 }, 96 97 "origin_path": { 98 Type: schema.TypeString, 99 Optional: true, 100 Computed: true, 101 }, 102 103 "querystring_caching_behaviour": { 104 Type: schema.TypeString, 105 Optional: true, 106 Default: "IgnoreQueryString", 107 ValidateFunc: validateCdnEndpointQuerystringCachingBehaviour, 108 }, 109 110 "content_types_to_compress": { 111 Type: schema.TypeSet, 112 Optional: true, 113 Computed: true, 114 Elem: &schema.Schema{ 115 Type: schema.TypeString, 116 }, 117 Set: schema.HashString, 118 }, 119 120 "is_compression_enabled": { 121 Type: schema.TypeBool, 122 Optional: true, 123 Default: false, 124 }, 125 126 "host_name": { 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 _, err := cdnEndpointsClient.Create(name, cdnEndpoint, profileName, resGroup, make(chan struct{})) 195 if err != nil { 196 return err 197 } 198 199 read, err := cdnEndpointsClient.Get(name, profileName, resGroup) 200 if err != nil { 201 return err 202 } 203 if read.ID == nil { 204 return fmt.Errorf("Cannot read CND Endpoint %s/%s (resource group %s) ID", profileName, name, resGroup) 205 } 206 207 d.SetId(*read.ID) 208 209 return resourceArmCdnEndpointRead(d, meta) 210 } 211 212 func resourceArmCdnEndpointRead(d *schema.ResourceData, meta interface{}) error { 213 cdnEndpointsClient := meta.(*ArmClient).cdnEndpointsClient 214 215 id, err := parseAzureResourceID(d.Id()) 216 if err != nil { 217 return err 218 } 219 resGroup := id.ResourceGroup 220 name := id.Path["endpoints"] 221 profileName := id.Path["profiles"] 222 if profileName == "" { 223 profileName = id.Path["Profiles"] 224 } 225 log.Printf("[INFO] Trying to find the AzureRM CDN Endpoint %s (Profile: %s, RG: %s)", name, profileName, resGroup) 226 resp, err := cdnEndpointsClient.Get(name, profileName, resGroup) 227 if resp.StatusCode == http.StatusNotFound { 228 d.SetId("") 229 return nil 230 } 231 if err != nil { 232 return fmt.Errorf("Error making Read request on Azure CDN Endpoint %s: %s", name, err) 233 } 234 235 d.Set("name", resp.Name) 236 d.Set("host_name", resp.Properties.HostName) 237 d.Set("is_compression_enabled", resp.Properties.IsCompressionEnabled) 238 d.Set("is_http_allowed", resp.Properties.IsHTTPAllowed) 239 d.Set("is_https_allowed", resp.Properties.IsHTTPSAllowed) 240 d.Set("querystring_caching_behaviour", resp.Properties.QueryStringCachingBehavior) 241 if resp.Properties.OriginHostHeader != nil && *resp.Properties.OriginHostHeader != "" { 242 d.Set("origin_host_header", resp.Properties.OriginHostHeader) 243 } 244 if resp.Properties.OriginPath != nil && *resp.Properties.OriginPath != "" { 245 d.Set("origin_path", resp.Properties.OriginPath) 246 } 247 if resp.Properties.ContentTypesToCompress != nil && len(*resp.Properties.ContentTypesToCompress) > 0 { 248 d.Set("content_types_to_compress", flattenAzureRMCdnEndpointContentTypes(resp.Properties.ContentTypesToCompress)) 249 } 250 d.Set("origin", flattenAzureRMCdnEndpointOrigin(resp.Properties.Origins)) 251 252 flattenAndSetTags(d, resp.Tags) 253 254 return nil 255 } 256 257 func resourceArmCdnEndpointUpdate(d *schema.ResourceData, meta interface{}) error { 258 cdnEndpointsClient := meta.(*ArmClient).cdnEndpointsClient 259 260 if !d.HasChange("tags") { 261 return nil 262 } 263 264 name := d.Get("name").(string) 265 resGroup := d.Get("resource_group_name").(string) 266 profileName := d.Get("profile_name").(string) 267 http_allowed := d.Get("is_http_allowed").(bool) 268 https_allowed := d.Get("is_https_allowed").(bool) 269 compression_enabled := d.Get("is_compression_enabled").(bool) 270 caching_behaviour := d.Get("querystring_caching_behaviour").(string) 271 newTags := d.Get("tags").(map[string]interface{}) 272 273 properties := cdn.EndpointPropertiesCreateUpdateParameters{ 274 IsHTTPAllowed: &http_allowed, 275 IsHTTPSAllowed: &https_allowed, 276 IsCompressionEnabled: &compression_enabled, 277 QueryStringCachingBehavior: cdn.QueryStringCachingBehavior(caching_behaviour), 278 } 279 280 if d.HasChange("origin") { 281 origins, originsErr := expandAzureRmCdnEndpointOrigins(d) 282 if originsErr != nil { 283 return fmt.Errorf("Error Building list of CDN Endpoint Origins: %s", originsErr) 284 } 285 if len(origins) > 0 { 286 properties.Origins = &origins 287 } 288 } 289 290 if d.HasChange("origin_host_header") { 291 host_header := d.Get("origin_host_header").(string) 292 properties.OriginHostHeader = &host_header 293 } 294 295 if d.HasChange("origin_path") { 296 origin_path := d.Get("origin_path").(string) 297 properties.OriginPath = &origin_path 298 } 299 300 if d.HasChange("content_types_to_compress") { 301 var content_types []string 302 ctypes := d.Get("content_types_to_compress").(*schema.Set).List() 303 for _, ct := range ctypes { 304 str := ct.(string) 305 content_types = append(content_types, str) 306 } 307 308 properties.ContentTypesToCompress = &content_types 309 } 310 311 updateProps := cdn.EndpointUpdateParameters{ 312 Tags: expandTags(newTags), 313 Properties: &properties, 314 } 315 316 _, err := cdnEndpointsClient.Update(name, updateProps, profileName, resGroup) 317 if err != nil { 318 return fmt.Errorf("Error issuing Azure ARM update request to update CDN Endpoint %q: %s", name, err) 319 } 320 321 return resourceArmCdnEndpointRead(d, meta) 322 } 323 324 func resourceArmCdnEndpointDelete(d *schema.ResourceData, meta interface{}) error { 325 client := meta.(*ArmClient).cdnEndpointsClient 326 327 id, err := parseAzureResourceID(d.Id()) 328 if err != nil { 329 return err 330 } 331 resGroup := id.ResourceGroup 332 profileName := id.Path["profiles"] 333 if profileName == "" { 334 profileName = id.Path["Profiles"] 335 } 336 name := id.Path["endpoints"] 337 338 accResp, err := client.DeleteIfExists(name, profileName, resGroup, make(chan struct{})) 339 if err != nil { 340 if accResp.StatusCode == http.StatusNotFound { 341 return nil 342 } 343 return fmt.Errorf("Error issuing AzureRM delete request for CDN Endpoint %q: %s", name, err) 344 } 345 346 return err 347 } 348 349 func validateCdnEndpointQuerystringCachingBehaviour(v interface{}, k string) (ws []string, errors []error) { 350 value := strings.ToLower(v.(string)) 351 cachingTypes := map[string]bool{ 352 "ignorequerystring": true, 353 "bypasscaching": true, 354 "usequerystring": true, 355 } 356 357 if !cachingTypes[value] { 358 errors = append(errors, fmt.Errorf("CDN Endpoint querystringCachingBehaviours can only be IgnoreQueryString, BypassCaching or UseQueryString")) 359 } 360 return 361 } 362 363 func resourceArmCdnEndpointOriginHash(v interface{}) int { 364 var buf bytes.Buffer 365 m := v.(map[string]interface{}) 366 buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) 367 buf.WriteString(fmt.Sprintf("%s-", m["host_name"].(string))) 368 369 return hashcode.String(buf.String()) 370 } 371 372 func expandAzureRmCdnEndpointOrigins(d *schema.ResourceData) ([]cdn.DeepCreatedOrigin, error) { 373 configs := d.Get("origin").(*schema.Set).List() 374 origins := make([]cdn.DeepCreatedOrigin, 0, len(configs)) 375 376 for _, configRaw := range configs { 377 data := configRaw.(map[string]interface{}) 378 379 host_name := data["host_name"].(string) 380 381 properties := cdn.DeepCreatedOriginProperties{ 382 HostName: &host_name, 383 } 384 385 if v, ok := data["https_port"]; ok { 386 https_port := int32(v.(int)) 387 properties.HTTPSPort = &https_port 388 389 } 390 391 if v, ok := data["http_port"]; ok { 392 http_port := int32(v.(int)) 393 properties.HTTPPort = &http_port 394 } 395 396 name := data["name"].(string) 397 398 origin := cdn.DeepCreatedOrigin{ 399 Name: &name, 400 Properties: &properties, 401 } 402 403 origins = append(origins, origin) 404 } 405 406 return origins, nil 407 } 408 409 func flattenAzureRMCdnEndpointOrigin(list *[]cdn.DeepCreatedOrigin) []map[string]interface{} { 410 result := make([]map[string]interface{}, 0, len(*list)) 411 for _, i := range *list { 412 l := map[string]interface{}{ 413 "name": *i.Name, 414 "host_name": *i.Properties.HostName, 415 } 416 417 if i.Properties.HTTPPort != nil { 418 l["http_port"] = *i.Properties.HTTPPort 419 } 420 if i.Properties.HTTPSPort != nil { 421 l["https_port"] = *i.Properties.HTTPSPort 422 } 423 result = append(result, l) 424 } 425 return result 426 } 427 428 func flattenAzureRMCdnEndpointContentTypes(list *[]string) []interface{} { 429 vs := make([]interface{}, 0, len(*list)) 430 for _, v := range *list { 431 vs = append(vs, v) 432 } 433 return vs 434 }