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