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