github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/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 _, error := cdnEndpointsClient.Create(resGroup, profileName, name, cdnEndpoint, make(<-chan struct{})) 194 err := <-error 195 if err != nil { 196 return err 197 } 198 199 read, err := cdnEndpointsClient.Get(resGroup, profileName, name) 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(resGroup, profileName, name) 227 if err != nil { 228 if resp.StatusCode == http.StatusNotFound { 229 d.SetId("") 230 return nil 231 } 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("resource_group_name", resGroup) 237 d.Set("location", azureRMNormalizeLocation(*resp.Location)) 238 d.Set("profile_name", profileName) 239 d.Set("host_name", resp.EndpointProperties.HostName) 240 d.Set("is_compression_enabled", resp.EndpointProperties.IsCompressionEnabled) 241 d.Set("is_http_allowed", resp.EndpointProperties.IsHTTPAllowed) 242 d.Set("is_https_allowed", resp.EndpointProperties.IsHTTPSAllowed) 243 d.Set("querystring_caching_behaviour", resp.EndpointProperties.QueryStringCachingBehavior) 244 if resp.EndpointProperties.OriginHostHeader != nil && *resp.EndpointProperties.OriginHostHeader != "" { 245 d.Set("origin_host_header", resp.EndpointProperties.OriginHostHeader) 246 } 247 if resp.EndpointProperties.OriginPath != nil && *resp.EndpointProperties.OriginPath != "" { 248 d.Set("origin_path", resp.EndpointProperties.OriginPath) 249 } 250 if resp.EndpointProperties.ContentTypesToCompress != nil { 251 d.Set("content_types_to_compress", flattenAzureRMCdnEndpointContentTypes(resp.EndpointProperties.ContentTypesToCompress)) 252 } 253 d.Set("origin", flattenAzureRMCdnEndpointOrigin(resp.EndpointProperties.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.EndpointPropertiesUpdateParameters{ 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_host_header") { 284 host_header := d.Get("origin_host_header").(string) 285 properties.OriginHostHeader = &host_header 286 } 287 288 if d.HasChange("origin_path") { 289 origin_path := d.Get("origin_path").(string) 290 properties.OriginPath = &origin_path 291 } 292 293 if d.HasChange("content_types_to_compress") { 294 var content_types []string 295 ctypes := d.Get("content_types_to_compress").(*schema.Set).List() 296 for _, ct := range ctypes { 297 str := ct.(string) 298 content_types = append(content_types, str) 299 } 300 301 properties.ContentTypesToCompress = &content_types 302 } 303 304 updateProps := cdn.EndpointUpdateParameters{ 305 Tags: expandTags(newTags), 306 EndpointPropertiesUpdateParameters: &properties, 307 } 308 309 _, error := cdnEndpointsClient.Update(resGroup, profileName, name, updateProps, make(<-chan struct{})) 310 err := <-error 311 if err != nil { 312 return fmt.Errorf("Error issuing Azure ARM update request to update CDN Endpoint %q: %s", name, err) 313 } 314 315 return resourceArmCdnEndpointRead(d, meta) 316 } 317 318 func resourceArmCdnEndpointDelete(d *schema.ResourceData, meta interface{}) error { 319 client := meta.(*ArmClient).cdnEndpointsClient 320 321 id, err := parseAzureResourceID(d.Id()) 322 if err != nil { 323 return err 324 } 325 resGroup := id.ResourceGroup 326 profileName := id.Path["profiles"] 327 if profileName == "" { 328 profileName = id.Path["Profiles"] 329 } 330 name := id.Path["endpoints"] 331 332 accResp, error := client.Delete(resGroup, profileName, name, make(<-chan struct{})) 333 resp := <-accResp 334 err = <-error 335 if err != nil { 336 if resp.StatusCode == http.StatusNotFound { 337 return nil 338 } 339 return fmt.Errorf("Error issuing AzureRM delete request for CDN Endpoint %q: %s", name, err) 340 } 341 342 return nil 343 } 344 345 func validateCdnEndpointQuerystringCachingBehaviour(v interface{}, k string) (ws []string, errors []error) { 346 value := strings.ToLower(v.(string)) 347 cachingTypes := map[string]bool{ 348 "ignorequerystring": true, 349 "bypasscaching": true, 350 "usequerystring": true, 351 } 352 353 if !cachingTypes[value] { 354 errors = append(errors, fmt.Errorf("CDN Endpoint querystringCachingBehaviours can only be IgnoreQueryString, BypassCaching or UseQueryString")) 355 } 356 return 357 } 358 359 func resourceArmCdnEndpointOriginHash(v interface{}) int { 360 var buf bytes.Buffer 361 m := v.(map[string]interface{}) 362 buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) 363 buf.WriteString(fmt.Sprintf("%s-", m["host_name"].(string))) 364 365 return hashcode.String(buf.String()) 366 } 367 368 func expandAzureRmCdnEndpointOrigins(d *schema.ResourceData) ([]cdn.DeepCreatedOrigin, error) { 369 configs := d.Get("origin").(*schema.Set).List() 370 origins := make([]cdn.DeepCreatedOrigin, 0, len(configs)) 371 372 for _, configRaw := range configs { 373 data := configRaw.(map[string]interface{}) 374 375 host_name := data["host_name"].(string) 376 377 properties := cdn.DeepCreatedOriginProperties{ 378 HostName: &host_name, 379 } 380 381 if v, ok := data["https_port"]; ok { 382 https_port := int32(v.(int)) 383 properties.HTTPSPort = &https_port 384 385 } 386 387 if v, ok := data["http_port"]; ok { 388 http_port := int32(v.(int)) 389 properties.HTTPPort = &http_port 390 } 391 392 name := data["name"].(string) 393 394 origin := cdn.DeepCreatedOrigin{ 395 Name: &name, 396 DeepCreatedOriginProperties: &properties, 397 } 398 399 origins = append(origins, origin) 400 } 401 402 return origins, nil 403 } 404 405 func flattenAzureRMCdnEndpointOrigin(list *[]cdn.DeepCreatedOrigin) []map[string]interface{} { 406 result := make([]map[string]interface{}, 0, len(*list)) 407 for _, i := range *list { 408 l := map[string]interface{}{ 409 "name": *i.Name, 410 "host_name": *i.DeepCreatedOriginProperties.HostName, 411 } 412 413 if i.DeepCreatedOriginProperties.HTTPPort != nil { 414 l["http_port"] = *i.DeepCreatedOriginProperties.HTTPPort 415 } 416 if i.DeepCreatedOriginProperties.HTTPSPort != nil { 417 l["https_port"] = *i.DeepCreatedOriginProperties.HTTPSPort 418 } 419 result = append(result, l) 420 } 421 return result 422 } 423 424 func flattenAzureRMCdnEndpointContentTypes(list *[]string) []interface{} { 425 vs := make([]interface{}, 0, len(*list)) 426 for _, v := range *list { 427 vs = append(vs, v) 428 } 429 return vs 430 }