From 6ee2bd4a55139996ccab93b47caa341ea03c711b Mon Sep 17 00:00:00 2001 From: James Nugent Date: Wed, 1 Jun 2016 19:44:08 -0500 Subject: [PATCH] provider/azurerm: Fix CDN resources --- builtin/providers/azurerm/provider.go | 6 +- .../azurerm/resource_arm_cdn_endpoint.go | 881 +++++++++--------- .../azurerm/resource_arm_cdn_endpoint_test.go | 424 +++++---- .../azurerm/resource_arm_cdn_profile.go | 353 ++++--- .../azurerm/resource_arm_cdn_profile_test.go | 410 ++++---- 5 files changed, 1020 insertions(+), 1054 deletions(-) diff --git a/builtin/providers/azurerm/provider.go b/builtin/providers/azurerm/provider.go index 3f15d07ab..395359b43 100644 --- a/builtin/providers/azurerm/provider.go +++ b/builtin/providers/azurerm/provider.go @@ -45,9 +45,9 @@ func Provider() terraform.ResourceProvider { ResourcesMap: map[string]*schema.Resource{ // These resources use the Azure ARM SDK - "azurerm_availability_set": resourceArmAvailabilitySet(), - //"azurerm_cdn_endpoint": resourceArmCdnEndpoint(), - //"azurerm_cdn_profile": resourceArmCdnProfile(), + "azurerm_availability_set": resourceArmAvailabilitySet(), + "azurerm_cdn_endpoint": resourceArmCdnEndpoint(), + "azurerm_cdn_profile": resourceArmCdnProfile(), "azurerm_local_network_gateway": resourceArmLocalNetworkGateway(), "azurerm_network_interface": resourceArmNetworkInterface(), "azurerm_network_security_group": resourceArmNetworkSecurityGroup(), diff --git a/builtin/providers/azurerm/resource_arm_cdn_endpoint.go b/builtin/providers/azurerm/resource_arm_cdn_endpoint.go index 01c290fa9..b0afc691a 100644 --- a/builtin/providers/azurerm/resource_arm_cdn_endpoint.go +++ b/builtin/providers/azurerm/resource_arm_cdn_endpoint.go @@ -1,451 +1,434 @@ package azurerm -//import ( -// "bytes" -// "fmt" -// "log" -// "net/http" -// "strings" -// "time" -// -// "github.com/Azure/azure-sdk-for-go/arm/cdn" -// "github.com/hashicorp/terraform/helper/hashcode" -// "github.com/hashicorp/terraform/helper/resource" -// "github.com/hashicorp/terraform/helper/schema" -//) -// -//func resourceArmCdnEndpoint() *schema.Resource { -// return &schema.Resource{ -// Create: resourceArmCdnEndpointCreate, -// Read: resourceArmCdnEndpointRead, -// Update: resourceArmCdnEndpointUpdate, -// Delete: resourceArmCdnEndpointDelete, -// -// Schema: map[string]*schema.Schema{ -// "name": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ForceNew: true, -// }, -// -// "location": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ForceNew: true, -// StateFunc: azureRMNormalizeLocation, -// }, -// -// "resource_group_name": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ForceNew: true, -// }, -// -// "profile_name": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ForceNew: true, -// }, -// -// "origin_host_header": &schema.Schema{ -// Type: schema.TypeString, -// Optional: true, -// Computed: true, -// }, -// -// "is_http_allowed": &schema.Schema{ -// Type: schema.TypeBool, -// Optional: true, -// Default: true, -// }, -// -// "is_https_allowed": &schema.Schema{ -// Type: schema.TypeBool, -// Optional: true, -// Default: true, -// }, -// -// "origin": &schema.Schema{ -// Type: schema.TypeSet, -// Required: true, -// Elem: &schema.Resource{ -// Schema: map[string]*schema.Schema{ -// "name": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// }, -// -// "host_name": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// }, -// -// "http_port": &schema.Schema{ -// Type: schema.TypeInt, -// Optional: true, -// Computed: true, -// }, -// -// "https_port": &schema.Schema{ -// Type: schema.TypeInt, -// Optional: true, -// Computed: true, -// }, -// }, -// }, -// Set: resourceArmCdnEndpointOriginHash, -// }, -// -// "origin_path": &schema.Schema{ -// Type: schema.TypeString, -// Optional: true, -// Computed: true, -// }, -// -// "querystring_caching_behaviour": &schema.Schema{ -// Type: schema.TypeString, -// Optional: true, -// Default: "IgnoreQueryString", -// ValidateFunc: validateCdnEndpointQuerystringCachingBehaviour, -// }, -// -// "content_types_to_compress": &schema.Schema{ -// Type: schema.TypeSet, -// Optional: true, -// Computed: true, -// Elem: &schema.Schema{Type: schema.TypeString}, -// Set: schema.HashString, -// }, -// -// "is_compression_enabled": &schema.Schema{ -// Type: schema.TypeBool, -// Optional: true, -// Default: false, -// }, -// -// "host_name": &schema.Schema{ -// Type: schema.TypeString, -// Computed: true, -// }, -// -// "tags": tagsSchema(), -// }, -// } -//} -// -//func resourceArmCdnEndpointCreate(d *schema.ResourceData, meta interface{}) error { -// client := meta.(*ArmClient) -// cdnEndpointsClient := client.cdnEndpointsClient -// -// log.Printf("[INFO] preparing arguments for Azure ARM CDN EndPoint creation.") -// -// name := d.Get("name").(string) -// location := d.Get("location").(string) -// resGroup := d.Get("resource_group_name").(string) -// profileName := d.Get("profile_name").(string) -// http_allowed := d.Get("is_http_allowed").(bool) -// https_allowed := d.Get("is_https_allowed").(bool) -// compression_enabled := d.Get("is_compression_enabled").(bool) -// caching_behaviour := d.Get("querystring_caching_behaviour").(string) -// tags := d.Get("tags").(map[string]interface{}) -// -// properties := cdn.EndpointPropertiesCreateUpdateParameters{ -// IsHTTPAllowed: &http_allowed, -// IsHTTPSAllowed: &https_allowed, -// IsCompressionEnabled: &compression_enabled, -// QueryStringCachingBehavior: cdn.QueryStringCachingBehavior(caching_behaviour), -// } -// -// origins, originsErr := expandAzureRmCdnEndpointOrigins(d) -// if originsErr != nil { -// return fmt.Errorf("Error Building list of CDN Endpoint Origins: %s", originsErr) -// } -// if len(origins) > 0 { -// properties.Origins = &origins -// } -// -// if v, ok := d.GetOk("origin_host_header"); ok { -// host_header := v.(string) -// properties.OriginHostHeader = &host_header -// } -// -// if v, ok := d.GetOk("origin_path"); ok { -// origin_path := v.(string) -// properties.OriginPath = &origin_path -// } -// -// if v, ok := d.GetOk("content_types_to_compress"); ok { -// var content_types []string -// ctypes := v.(*schema.Set).List() -// for _, ct := range ctypes { -// str := ct.(string) -// content_types = append(content_types, str) -// } -// -// properties.ContentTypesToCompress = &content_types -// } -// -// cdnEndpoint := cdn.EndpointCreateParameters{ -// Location: &location, -// Properties: &properties, -// Tags: expandTags(tags), -// } -// -// resp, err := cdnEndpointsClient.Create(name, cdnEndpoint, profileName, resGroup) -// if err != nil { -// return err -// } -// -// d.SetId(*resp.ID) -// -// log.Printf("[DEBUG] Waiting for CDN Endpoint (%s) to become available", name) -// stateConf := &resource.StateChangeConf{ -// Pending: []string{"Accepted", "Updating", "Creating"}, -// Target: []string{"Succeeded"}, -// Refresh: cdnEndpointStateRefreshFunc(client, resGroup, profileName, name), -// Timeout: 10 * time.Minute, -// } -// if _, err := stateConf.WaitForState(); err != nil { -// return fmt.Errorf("Error waiting for CDN Endpoint (%s) to become available: %s", name, err) -// } -// -// return resourceArmCdnEndpointRead(d, meta) -//} -// -//func resourceArmCdnEndpointRead(d *schema.ResourceData, meta interface{}) error { -// cdnEndpointsClient := meta.(*ArmClient).cdnEndpointsClient -// -// id, err := parseAzureResourceID(d.Id()) -// if err != nil { -// return err -// } -// resGroup := id.ResourceGroup -// name := id.Path["endpoints"] -// profileName := id.Path["profiles"] -// if profileName == "" { -// profileName = id.Path["Profiles"] -// } -// log.Printf("[INFO] Trying to find the AzureRM CDN Endpoint %s (Profile: %s, RG: %s)", name, profileName, resGroup) -// resp, err := cdnEndpointsClient.Get(name, profileName, resGroup) -// if resp.StatusCode == http.StatusNotFound { -// d.SetId("") -// return nil -// } -// if err != nil { -// return fmt.Errorf("Error making Read request on Azure CDN Endpoint %s: %s", name, err) -// } -// -// d.Set("name", resp.Name) -// d.Set("host_name", resp.Properties.HostName) -// d.Set("is_compression_enabled", resp.Properties.IsCompressionEnabled) -// d.Set("is_http_allowed", resp.Properties.IsHTTPAllowed) -// d.Set("is_https_allowed", resp.Properties.IsHTTPSAllowed) -// d.Set("querystring_caching_behaviour", resp.Properties.QueryStringCachingBehavior) -// if resp.Properties.OriginHostHeader != nil && *resp.Properties.OriginHostHeader != "" { -// d.Set("origin_host_header", resp.Properties.OriginHostHeader) -// } -// if resp.Properties.OriginPath != nil && *resp.Properties.OriginPath != "" { -// d.Set("origin_path", resp.Properties.OriginPath) -// } -// if resp.Properties.ContentTypesToCompress != nil && len(*resp.Properties.ContentTypesToCompress) > 0 { -// d.Set("content_types_to_compress", flattenAzureRMCdnEndpointContentTypes(resp.Properties.ContentTypesToCompress)) -// } -// d.Set("origin", flattenAzureRMCdnEndpointOrigin(resp.Properties.Origins)) -// -// flattenAndSetTags(d, resp.Tags) -// -// return nil -//} -// -//func resourceArmCdnEndpointUpdate(d *schema.ResourceData, meta interface{}) error { -// cdnEndpointsClient := meta.(*ArmClient).cdnEndpointsClient -// -// if !d.HasChange("tags") { -// return nil -// } -// -// name := d.Get("name").(string) -// resGroup := d.Get("resource_group_name").(string) -// profileName := d.Get("profile_name").(string) -// http_allowed := d.Get("is_http_allowed").(bool) -// https_allowed := d.Get("is_https_allowed").(bool) -// compression_enabled := d.Get("is_compression_enabled").(bool) -// caching_behaviour := d.Get("querystring_caching_behaviour").(string) -// newTags := d.Get("tags").(map[string]interface{}) -// -// properties := cdn.EndpointPropertiesCreateUpdateParameters{ -// IsHTTPAllowed: &http_allowed, -// IsHTTPSAllowed: &https_allowed, -// IsCompressionEnabled: &compression_enabled, -// QueryStringCachingBehavior: cdn.QueryStringCachingBehavior(caching_behaviour), -// } -// -// if d.HasChange("origin") { -// origins, originsErr := expandAzureRmCdnEndpointOrigins(d) -// if originsErr != nil { -// return fmt.Errorf("Error Building list of CDN Endpoint Origins: %s", originsErr) -// } -// if len(origins) > 0 { -// properties.Origins = &origins -// } -// } -// -// if d.HasChange("origin_host_header") { -// host_header := d.Get("origin_host_header").(string) -// properties.OriginHostHeader = &host_header -// } -// -// if d.HasChange("origin_path") { -// origin_path := d.Get("origin_path").(string) -// properties.OriginPath = &origin_path -// } -// -// if d.HasChange("content_types_to_compress") { -// var content_types []string -// ctypes := d.Get("content_types_to_compress").(*schema.Set).List() -// for _, ct := range ctypes { -// str := ct.(string) -// content_types = append(content_types, str) -// } -// -// properties.ContentTypesToCompress = &content_types -// } -// -// updateProps := cdn.EndpointUpdateParameters{ -// Tags: expandTags(newTags), -// Properties: &properties, -// } -// -// _, err := cdnEndpointsClient.Update(name, updateProps, profileName, resGroup) -// if err != nil { -// return fmt.Errorf("Error issuing Azure ARM update request to update CDN Endpoint %q: %s", name, err) -// } -// -// return resourceArmCdnEndpointRead(d, meta) -//} -// -//func resourceArmCdnEndpointDelete(d *schema.ResourceData, meta interface{}) error { -// client := meta.(*ArmClient).cdnEndpointsClient -// -// id, err := parseAzureResourceID(d.Id()) -// if err != nil { -// return err -// } -// resGroup := id.ResourceGroup -// profileName := id.Path["profiles"] -// if profileName == "" { -// profileName = id.Path["Profiles"] -// } -// name := id.Path["endpoints"] -// -// accResp, err := client.DeleteIfExists(name, profileName, resGroup) -// if err != nil { -// if accResp.StatusCode == http.StatusNotFound { -// return nil -// } -// return fmt.Errorf("Error issuing AzureRM delete request for CDN Endpoint %q: %s", name, err) -// } -// _, err = pollIndefinitelyAsNeeded(client.Client, accResp.Response, http.StatusNotFound) -// if err != nil { -// return fmt.Errorf("Error polling for AzureRM delete request for CDN Endpoint %q: %s", name, err) -// } -// -// return err -//} -// -//func cdnEndpointStateRefreshFunc(client *ArmClient, resourceGroupName string, profileName string, name string) resource.StateRefreshFunc { -// return func() (interface{}, string, error) { -// res, err := client.cdnEndpointsClient.Get(name, profileName, resourceGroupName) -// if err != nil { -// return nil, "", fmt.Errorf("Error issuing read request in cdnEndpointStateRefreshFunc to Azure ARM for CDN Endpoint '%s' (RG: '%s'): %s", name, resourceGroupName, err) -// } -// return res, string(res.Properties.ProvisioningState), nil -// } -//} -// -//func validateCdnEndpointQuerystringCachingBehaviour(v interface{}, k string) (ws []string, errors []error) { -// value := strings.ToLower(v.(string)) -// cachingTypes := map[string]bool{ -// "ignorequerystring": true, -// "bypasscaching": true, -// "usequerystring": true, -// } -// -// if !cachingTypes[value] { -// errors = append(errors, fmt.Errorf("CDN Endpoint querystringCachingBehaviours can only be IgnoreQueryString, BypassCaching or UseQueryString")) -// } -// return -//} -// -//func resourceArmCdnEndpointOriginHash(v interface{}) int { -// var buf bytes.Buffer -// m := v.(map[string]interface{}) -// buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) -// buf.WriteString(fmt.Sprintf("%s-", m["host_name"].(string))) -// -// return hashcode.String(buf.String()) -//} -// -//func expandAzureRmCdnEndpointOrigins(d *schema.ResourceData) ([]cdn.DeepCreatedOrigin, error) { -// configs := d.Get("origin").(*schema.Set).List() -// origins := make([]cdn.DeepCreatedOrigin, 0, len(configs)) -// -// for _, configRaw := range configs { -// data := configRaw.(map[string]interface{}) -// -// host_name := data["host_name"].(string) -// -// properties := cdn.DeepCreatedOriginProperties{ -// HostName: &host_name, -// } -// -// if v, ok := data["https_port"]; ok { -// https_port := v.(int) -// properties.HTTPSPort = &https_port -// -// } -// -// if v, ok := data["http_port"]; ok { -// http_port := v.(int) -// properties.HTTPPort = &http_port -// } -// -// name := data["name"].(string) -// -// origin := cdn.DeepCreatedOrigin{ -// Name: &name, -// Properties: &properties, -// } -// -// origins = append(origins, origin) -// } -// -// return origins, nil -//} -// -//func flattenAzureRMCdnEndpointOrigin(list *[]cdn.DeepCreatedOrigin) []map[string]interface{} { -// result := make([]map[string]interface{}, 0, len(*list)) -// for _, i := range *list { -// l := map[string]interface{}{ -// "name": *i.Name, -// "host_name": *i.Properties.HostName, -// } -// -// if i.Properties.HTTPPort != nil { -// l["http_port"] = *i.Properties.HTTPPort -// } -// if i.Properties.HTTPSPort != nil { -// l["https_port"] = *i.Properties.HTTPSPort -// } -// result = append(result, l) -// } -// return result -//} -// -//func flattenAzureRMCdnEndpointContentTypes(list *[]string) []interface{} { -// vs := make([]interface{}, 0, len(*list)) -// for _, v := range *list { -// vs = append(vs, v) -// } -// return vs -//} +import ( + "bytes" + "fmt" + "log" + "net/http" + "strings" + + "github.com/Azure/azure-sdk-for-go/arm/cdn" + "github.com/hashicorp/terraform/helper/hashcode" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceArmCdnEndpoint() *schema.Resource { + return &schema.Resource{ + Create: resourceArmCdnEndpointCreate, + Read: resourceArmCdnEndpointRead, + Update: resourceArmCdnEndpointUpdate, + Delete: resourceArmCdnEndpointDelete, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "location": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + StateFunc: azureRMNormalizeLocation, + }, + + "resource_group_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "profile_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "origin_host_header": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "is_http_allowed": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "is_https_allowed": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "origin": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + + "host_name": { + Type: schema.TypeString, + Required: true, + }, + + "http_port": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + + "https_port": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + }, + }, + Set: resourceArmCdnEndpointOriginHash, + }, + + "origin_path": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "querystring_caching_behaviour": { + Type: schema.TypeString, + Optional: true, + Default: "IgnoreQueryString", + ValidateFunc: validateCdnEndpointQuerystringCachingBehaviour, + }, + + "content_types_to_compress": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Set: schema.HashString, + }, + + "is_compression_enabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "host_name": { + Type: schema.TypeString, + Computed: true, + }, + + "tags": tagsSchema(), + }, + } +} + +func resourceArmCdnEndpointCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient) + cdnEndpointsClient := client.cdnEndpointsClient + + log.Printf("[INFO] preparing arguments for Azure ARM CDN EndPoint creation.") + + name := d.Get("name").(string) + location := d.Get("location").(string) + resGroup := d.Get("resource_group_name").(string) + profileName := d.Get("profile_name").(string) + http_allowed := d.Get("is_http_allowed").(bool) + https_allowed := d.Get("is_https_allowed").(bool) + compression_enabled := d.Get("is_compression_enabled").(bool) + caching_behaviour := d.Get("querystring_caching_behaviour").(string) + tags := d.Get("tags").(map[string]interface{}) + + properties := cdn.EndpointPropertiesCreateUpdateParameters{ + IsHTTPAllowed: &http_allowed, + IsHTTPSAllowed: &https_allowed, + IsCompressionEnabled: &compression_enabled, + QueryStringCachingBehavior: cdn.QueryStringCachingBehavior(caching_behaviour), + } + + origins, originsErr := expandAzureRmCdnEndpointOrigins(d) + if originsErr != nil { + return fmt.Errorf("Error Building list of CDN Endpoint Origins: %s", originsErr) + } + if len(origins) > 0 { + properties.Origins = &origins + } + + if v, ok := d.GetOk("origin_host_header"); ok { + host_header := v.(string) + properties.OriginHostHeader = &host_header + } + + if v, ok := d.GetOk("origin_path"); ok { + origin_path := v.(string) + properties.OriginPath = &origin_path + } + + if v, ok := d.GetOk("content_types_to_compress"); ok { + var content_types []string + ctypes := v.(*schema.Set).List() + for _, ct := range ctypes { + str := ct.(string) + content_types = append(content_types, str) + } + + properties.ContentTypesToCompress = &content_types + } + + cdnEndpoint := cdn.EndpointCreateParameters{ + Location: &location, + Properties: &properties, + Tags: expandTags(tags), + } + + _, err := cdnEndpointsClient.Create(name, cdnEndpoint, profileName, resGroup, make(chan struct{})) + if err != nil { + return err + } + + read, err := cdnEndpointsClient.Get(name, profileName, resGroup) + if err != nil { + return err + } + if read.ID == nil { + return fmt.Errorf("Cannot read CND Endpoint %s/%s (resource group %s) ID", profileName, name, resGroup) + } + + d.SetId(*read.ID) + + return resourceArmCdnEndpointRead(d, meta) +} + +func resourceArmCdnEndpointRead(d *schema.ResourceData, meta interface{}) error { + cdnEndpointsClient := meta.(*ArmClient).cdnEndpointsClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["endpoints"] + profileName := id.Path["profiles"] + if profileName == "" { + profileName = id.Path["Profiles"] + } + log.Printf("[INFO] Trying to find the AzureRM CDN Endpoint %s (Profile: %s, RG: %s)", name, profileName, resGroup) + resp, err := cdnEndpointsClient.Get(name, profileName, resGroup) + if resp.StatusCode == http.StatusNotFound { + d.SetId("") + return nil + } + if err != nil { + return fmt.Errorf("Error making Read request on Azure CDN Endpoint %s: %s", name, err) + } + + d.Set("name", resp.Name) + d.Set("host_name", resp.Properties.HostName) + d.Set("is_compression_enabled", resp.Properties.IsCompressionEnabled) + d.Set("is_http_allowed", resp.Properties.IsHTTPAllowed) + d.Set("is_https_allowed", resp.Properties.IsHTTPSAllowed) + d.Set("querystring_caching_behaviour", resp.Properties.QueryStringCachingBehavior) + if resp.Properties.OriginHostHeader != nil && *resp.Properties.OriginHostHeader != "" { + d.Set("origin_host_header", resp.Properties.OriginHostHeader) + } + if resp.Properties.OriginPath != nil && *resp.Properties.OriginPath != "" { + d.Set("origin_path", resp.Properties.OriginPath) + } + if resp.Properties.ContentTypesToCompress != nil && len(*resp.Properties.ContentTypesToCompress) > 0 { + d.Set("content_types_to_compress", flattenAzureRMCdnEndpointContentTypes(resp.Properties.ContentTypesToCompress)) + } + d.Set("origin", flattenAzureRMCdnEndpointOrigin(resp.Properties.Origins)) + + flattenAndSetTags(d, resp.Tags) + + return nil +} + +func resourceArmCdnEndpointUpdate(d *schema.ResourceData, meta interface{}) error { + cdnEndpointsClient := meta.(*ArmClient).cdnEndpointsClient + + if !d.HasChange("tags") { + return nil + } + + name := d.Get("name").(string) + resGroup := d.Get("resource_group_name").(string) + profileName := d.Get("profile_name").(string) + http_allowed := d.Get("is_http_allowed").(bool) + https_allowed := d.Get("is_https_allowed").(bool) + compression_enabled := d.Get("is_compression_enabled").(bool) + caching_behaviour := d.Get("querystring_caching_behaviour").(string) + newTags := d.Get("tags").(map[string]interface{}) + + properties := cdn.EndpointPropertiesCreateUpdateParameters{ + IsHTTPAllowed: &http_allowed, + IsHTTPSAllowed: &https_allowed, + IsCompressionEnabled: &compression_enabled, + QueryStringCachingBehavior: cdn.QueryStringCachingBehavior(caching_behaviour), + } + + if d.HasChange("origin") { + origins, originsErr := expandAzureRmCdnEndpointOrigins(d) + if originsErr != nil { + return fmt.Errorf("Error Building list of CDN Endpoint Origins: %s", originsErr) + } + if len(origins) > 0 { + properties.Origins = &origins + } + } + + if d.HasChange("origin_host_header") { + host_header := d.Get("origin_host_header").(string) + properties.OriginHostHeader = &host_header + } + + if d.HasChange("origin_path") { + origin_path := d.Get("origin_path").(string) + properties.OriginPath = &origin_path + } + + if d.HasChange("content_types_to_compress") { + var content_types []string + ctypes := d.Get("content_types_to_compress").(*schema.Set).List() + for _, ct := range ctypes { + str := ct.(string) + content_types = append(content_types, str) + } + + properties.ContentTypesToCompress = &content_types + } + + updateProps := cdn.EndpointUpdateParameters{ + Tags: expandTags(newTags), + Properties: &properties, + } + + _, err := cdnEndpointsClient.Update(name, updateProps, profileName, resGroup) + if err != nil { + return fmt.Errorf("Error issuing Azure ARM update request to update CDN Endpoint %q: %s", name, err) + } + + return resourceArmCdnEndpointRead(d, meta) +} + +func resourceArmCdnEndpointDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).cdnEndpointsClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + profileName := id.Path["profiles"] + if profileName == "" { + profileName = id.Path["Profiles"] + } + name := id.Path["endpoints"] + + accResp, err := client.DeleteIfExists(name, profileName, resGroup, make(chan struct{})) + if err != nil { + if accResp.StatusCode == http.StatusNotFound { + return nil + } + return fmt.Errorf("Error issuing AzureRM delete request for CDN Endpoint %q: %s", name, err) + } + + return err +} + +func validateCdnEndpointQuerystringCachingBehaviour(v interface{}, k string) (ws []string, errors []error) { + value := strings.ToLower(v.(string)) + cachingTypes := map[string]bool{ + "ignorequerystring": true, + "bypasscaching": true, + "usequerystring": true, + } + + if !cachingTypes[value] { + errors = append(errors, fmt.Errorf("CDN Endpoint querystringCachingBehaviours can only be IgnoreQueryString, BypassCaching or UseQueryString")) + } + return +} + +func resourceArmCdnEndpointOriginHash(v interface{}) int { + var buf bytes.Buffer + m := v.(map[string]interface{}) + buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) + buf.WriteString(fmt.Sprintf("%s-", m["host_name"].(string))) + + return hashcode.String(buf.String()) +} + +func expandAzureRmCdnEndpointOrigins(d *schema.ResourceData) ([]cdn.DeepCreatedOrigin, error) { + configs := d.Get("origin").(*schema.Set).List() + origins := make([]cdn.DeepCreatedOrigin, 0, len(configs)) + + for _, configRaw := range configs { + data := configRaw.(map[string]interface{}) + + host_name := data["host_name"].(string) + + properties := cdn.DeepCreatedOriginProperties{ + HostName: &host_name, + } + + if v, ok := data["https_port"]; ok { + https_port := int32(v.(int)) + properties.HTTPSPort = &https_port + + } + + if v, ok := data["http_port"]; ok { + http_port := int32(v.(int)) + properties.HTTPPort = &http_port + } + + name := data["name"].(string) + + origin := cdn.DeepCreatedOrigin{ + Name: &name, + Properties: &properties, + } + + origins = append(origins, origin) + } + + return origins, nil +} + +func flattenAzureRMCdnEndpointOrigin(list *[]cdn.DeepCreatedOrigin) []map[string]interface{} { + result := make([]map[string]interface{}, 0, len(*list)) + for _, i := range *list { + l := map[string]interface{}{ + "name": *i.Name, + "host_name": *i.Properties.HostName, + } + + if i.Properties.HTTPPort != nil { + l["http_port"] = *i.Properties.HTTPPort + } + if i.Properties.HTTPSPort != nil { + l["https_port"] = *i.Properties.HTTPSPort + } + result = append(result, l) + } + return result +} + +func flattenAzureRMCdnEndpointContentTypes(list *[]string) []interface{} { + vs := make([]interface{}, 0, len(*list)) + for _, v := range *list { + vs = append(vs, v) + } + return vs +} diff --git a/builtin/providers/azurerm/resource_arm_cdn_endpoint_test.go b/builtin/providers/azurerm/resource_arm_cdn_endpoint_test.go index bd2a93fc5..705564ebc 100644 --- a/builtin/providers/azurerm/resource_arm_cdn_endpoint_test.go +++ b/builtin/providers/azurerm/resource_arm_cdn_endpoint_test.go @@ -1,215 +1,213 @@ package azurerm -//import ( -// "fmt" -// "net/http" -// "testing" -// -// "github.com/hashicorp/terraform/helper/acctest" -// "github.com/hashicorp/terraform/helper/resource" -// "github.com/hashicorp/terraform/terraform" -//) -// -//func TestAccAzureRMCdnEndpoint_basic(t *testing.T) { -// -// ri := acctest.RandInt() -// config := fmt.Sprintf(testAccAzureRMCdnEndpoint_basic, ri, ri, ri) -// -// resource.Test(t, resource.TestCase{ -// PreCheck: func() { testAccPreCheck(t) }, -// Providers: testAccProviders, -// CheckDestroy: testCheckAzureRMCdnEndpointDestroy, -// Steps: []resource.TestStep{ -// resource.TestStep{ -// Config: config, -// Check: resource.ComposeTestCheckFunc( -// testCheckAzureRMCdnEndpointExists("azurerm_cdn_endpoint.test"), -// ), -// }, -// }, -// }) -//} -// -//func TestAccAzureRMCdnEndpoints_withTags(t *testing.T) { -// -// ri := acctest.RandInt() -// preConfig := fmt.Sprintf(testAccAzureRMCdnEndpoint_withTags, ri, ri, ri) -// postConfig := fmt.Sprintf(testAccAzureRMCdnEndpoint_withTagsUpdate, ri, ri, ri) -// -// resource.Test(t, resource.TestCase{ -// PreCheck: func() { testAccPreCheck(t) }, -// Providers: testAccProviders, -// CheckDestroy: testCheckAzureRMCdnEndpointDestroy, -// Steps: []resource.TestStep{ -// resource.TestStep{ -// Config: preConfig, -// Check: resource.ComposeTestCheckFunc( -// testCheckAzureRMCdnEndpointExists("azurerm_cdn_endpoint.test"), -// resource.TestCheckResourceAttr( -// "azurerm_cdn_endpoint.test", "tags.#", "2"), -// resource.TestCheckResourceAttr( -// "azurerm_cdn_endpoint.test", "tags.environment", "Production"), -// resource.TestCheckResourceAttr( -// "azurerm_cdn_endpoint.test", "tags.cost_center", "MSFT"), -// ), -// }, -// -// resource.TestStep{ -// Config: postConfig, -// Check: resource.ComposeTestCheckFunc( -// testCheckAzureRMCdnEndpointExists("azurerm_cdn_endpoint.test"), -// resource.TestCheckResourceAttr( -// "azurerm_cdn_endpoint.test", "tags.#", "1"), -// resource.TestCheckResourceAttr( -// "azurerm_cdn_endpoint.test", "tags.environment", "staging"), -// ), -// }, -// }, -// }) -//} -// -//func testCheckAzureRMCdnEndpointExists(name string) resource.TestCheckFunc { -// return func(s *terraform.State) error { -// // Ensure we have enough information in state to look up in API -// rs, ok := s.RootModule().Resources[name] -// if !ok { -// return fmt.Errorf("Not found: %s", name) -// } -// -// name := rs.Primary.Attributes["name"] -// profileName := rs.Primary.Attributes["profile_name"] -// resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] -// if !hasResourceGroup { -// return fmt.Errorf("Bad: no resource group found in state for cdn endpoint: %s", name) -// } -// -// conn := testAccProvider.Meta().(*ArmClient).cdnEndpointsClient -// -// resp, err := conn.Get(name, profileName, resourceGroup) -// if err != nil { -// return fmt.Errorf("Bad: Get on cdnEndpointsClient: %s", err) -// } -// -// if resp.StatusCode == http.StatusNotFound { -// return fmt.Errorf("Bad: CDN Endpoint %q (resource group: %q) does not exist", name, resourceGroup) -// } -// -// return nil -// } -//} -// -//func testCheckAzureRMCdnEndpointDestroy(s *terraform.State) error { -// conn := testAccProvider.Meta().(*ArmClient).cdnEndpointsClient -// -// for _, rs := range s.RootModule().Resources { -// if rs.Type != "azurerm_cdn_endpoint" { -// continue -// } -// -// name := rs.Primary.Attributes["name"] -// resourceGroup := rs.Primary.Attributes["resource_group_name"] -// profileName := rs.Primary.Attributes["profile_name"] -// -// resp, err := conn.Get(name, profileName, resourceGroup) -// -// if err != nil { -// return nil -// } -// -// if resp.StatusCode != http.StatusNotFound { -// return fmt.Errorf("CDN Endpoint still exists:\n%#v", resp.Properties) -// } -// } -// -// return nil -//} -// -//var testAccAzureRMCdnEndpoint_basic = ` -//resource "azurerm_resource_group" "test" { -// name = "acctestrg-%d" -// location = "West US" -//} -//resource "azurerm_cdn_profile" "test" { -// name = "acctestcdnprof%d" -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -// sku = "Standard" -//} -// -//resource "azurerm_cdn_endpoint" "test" { -// name = "acctestcdnend%d" -// profile_name = "${azurerm_cdn_profile.test.name}" -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -// -// origin { -// name = "acceptanceTestCdnOrigin1" -// host_name = "www.example.com" -// https_port = 443 -// http_port = 80 -// } -//} -//` -// -//var testAccAzureRMCdnEndpoint_withTags = ` -//resource "azurerm_resource_group" "test" { -// name = "acctestrg-%d" -// location = "West US" -//} -//resource "azurerm_cdn_profile" "test" { -// name = "acctestcdnprof%d" -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -// sku = "Standard" -//} -// -//resource "azurerm_cdn_endpoint" "test" { -// name = "acctestcdnend%d" -// profile_name = "${azurerm_cdn_profile.test.name}" -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -// -// origin { -// name = "acceptanceTestCdnOrigin2" -// host_name = "www.example.com" -// https_port = 443 -// http_port = 80 -// } -// -// tags { -// environment = "Production" -// cost_center = "MSFT" -// } -//} -//` -// -//var testAccAzureRMCdnEndpoint_withTagsUpdate = ` -//resource "azurerm_resource_group" "test" { -// name = "acctestrg-%d" -// location = "West US" -//} -//resource "azurerm_cdn_profile" "test" { -// name = "acctestcdnprof%d" -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -// sku = "Standard" -//} -// -//resource "azurerm_cdn_endpoint" "test" { -// name = "acctestcdnend%d" -// profile_name = "${azurerm_cdn_profile.test.name}" -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -// -// origin { -// name = "acceptanceTestCdnOrigin2" -// host_name = "www.example.com" -// https_port = 443 -// http_port = 80 -// } -// -// tags { -// environment = "staging" -// } -//} -//` +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAzureRMCdnEndpoint_basic(t *testing.T) { + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMCdnEndpoint_basic, ri, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCdnEndpointDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMCdnEndpointExists("azurerm_cdn_endpoint.test"), + ), + }, + }, + }) +} + +func TestAccAzureRMCdnEndpoint_withTags(t *testing.T) { + ri := acctest.RandInt() + preConfig := fmt.Sprintf(testAccAzureRMCdnEndpoint_withTags, ri, ri, ri) + postConfig := fmt.Sprintf(testAccAzureRMCdnEndpoint_withTagsUpdate, ri, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCdnEndpointDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMCdnEndpointExists("azurerm_cdn_endpoint.test"), + resource.TestCheckResourceAttr( + "azurerm_cdn_endpoint.test", "tags.#", "2"), + resource.TestCheckResourceAttr( + "azurerm_cdn_endpoint.test", "tags.environment", "Production"), + resource.TestCheckResourceAttr( + "azurerm_cdn_endpoint.test", "tags.cost_center", "MSFT"), + ), + }, + + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMCdnEndpointExists("azurerm_cdn_endpoint.test"), + resource.TestCheckResourceAttr( + "azurerm_cdn_endpoint.test", "tags.#", "1"), + resource.TestCheckResourceAttr( + "azurerm_cdn_endpoint.test", "tags.environment", "staging"), + ), + }, + }, + }) +} + +func testCheckAzureRMCdnEndpointExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + name := rs.Primary.Attributes["name"] + profileName := rs.Primary.Attributes["profile_name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for cdn endpoint: %s", name) + } + + conn := testAccProvider.Meta().(*ArmClient).cdnEndpointsClient + + resp, err := conn.Get(name, profileName, resourceGroup) + if err != nil { + return fmt.Errorf("Bad: Get on cdnEndpointsClient: %s", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: CDN Endpoint %q (resource group: %q) does not exist", name, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMCdnEndpointDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).cdnEndpointsClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_cdn_endpoint" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + profileName := rs.Primary.Attributes["profile_name"] + + resp, err := conn.Get(name, profileName, resourceGroup) + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("CDN Endpoint still exists:\n%#v", resp.Properties) + } + } + + return nil +} + +var testAccAzureRMCdnEndpoint_basic = ` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "West US" +} +resource "azurerm_cdn_profile" "test" { + name = "acctestcdnprof%d" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" +} + +resource "azurerm_cdn_endpoint" "test" { + name = "acctestcdnend%d" + profile_name = "${azurerm_cdn_profile.test.name}" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + + origin { + name = "acceptanceTestCdnOrigin1" + host_name = "www.example.com" + https_port = 443 + http_port = 80 + } +} +` + +var testAccAzureRMCdnEndpoint_withTags = ` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "West US" +} +resource "azurerm_cdn_profile" "test" { + name = "acctestcdnprof%d" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" +} + +resource "azurerm_cdn_endpoint" "test" { + name = "acctestcdnend%d" + profile_name = "${azurerm_cdn_profile.test.name}" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + + origin { + name = "acceptanceTestCdnOrigin2" + host_name = "www.example.com" + https_port = 443 + http_port = 80 + } + + tags { + environment = "Production" + cost_center = "MSFT" + } +} +` + +var testAccAzureRMCdnEndpoint_withTagsUpdate = ` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "West US" +} +resource "azurerm_cdn_profile" "test" { + name = "acctestcdnprof%d" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" +} + +resource "azurerm_cdn_endpoint" "test" { + name = "acctestcdnend%d" + profile_name = "${azurerm_cdn_profile.test.name}" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + + origin { + name = "acceptanceTestCdnOrigin2" + host_name = "www.example.com" + https_port = 443 + http_port = 80 + } + + tags { + environment = "staging" + } +} +` diff --git a/builtin/providers/azurerm/resource_arm_cdn_profile.go b/builtin/providers/azurerm/resource_arm_cdn_profile.go index c3044b940..074f9b855 100644 --- a/builtin/providers/azurerm/resource_arm_cdn_profile.go +++ b/builtin/providers/azurerm/resource_arm_cdn_profile.go @@ -1,186 +1,171 @@ package azurerm -//import ( -// "fmt" -// "log" -// "net/http" -// "strings" -// "time" -// -// "github.com/Azure/azure-sdk-for-go/arm/cdn" -// "github.com/hashicorp/terraform/helper/resource" -// "github.com/hashicorp/terraform/helper/schema" -//) -// -//func resourceArmCdnProfile() *schema.Resource { -// return &schema.Resource{ -// Create: resourceArmCdnProfileCreate, -// Read: resourceArmCdnProfileRead, -// Update: resourceArmCdnProfileUpdate, -// Delete: resourceArmCdnProfileDelete, -// -// Schema: map[string]*schema.Schema{ -// "name": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ForceNew: true, -// }, -// -// "location": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ForceNew: true, -// StateFunc: azureRMNormalizeLocation, -// }, -// -// "resource_group_name": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ForceNew: true, -// }, -// -// "sku": &schema.Schema{ -// Type: schema.TypeString, -// Required: true, -// ForceNew: true, -// ValidateFunc: validateCdnProfileSku, -// }, -// -// "tags": tagsSchema(), -// }, -// } -//} -// -//func resourceArmCdnProfileCreate(d *schema.ResourceData, meta interface{}) error { -// client := meta.(*ArmClient) -// cdnProfilesClient := client.cdnProfilesClient -// -// log.Printf("[INFO] preparing arguments for Azure ARM CDN Profile creation.") -// -// name := d.Get("name").(string) -// location := d.Get("location").(string) -// resGroup := d.Get("resource_group_name").(string) -// sku := d.Get("sku").(string) -// tags := d.Get("tags").(map[string]interface{}) -// -// properties := cdn.ProfilePropertiesCreateParameters{ -// Sku: &cdn.Sku{ -// Name: cdn.SkuName(sku), -// }, -// } -// -// cdnProfile := cdn.ProfileCreateParameters{ -// Location: &location, -// Properties: &properties, -// Tags: expandTags(tags), -// } -// -// resp, err := cdnProfilesClient.Create(name, cdnProfile, resGroup) -// if err != nil { -// return err -// } -// -// d.SetId(*resp.ID) -// -// log.Printf("[DEBUG] Waiting for CDN Profile (%s) to become available", name) -// stateConf := &resource.StateChangeConf{ -// Pending: []string{"Accepted", "Updating", "Creating"}, -// Target: []string{"Succeeded"}, -// Refresh: cdnProfileStateRefreshFunc(client, resGroup, name), -// Timeout: 10 * time.Minute, -// } -// if _, err := stateConf.WaitForState(); err != nil { -// return fmt.Errorf("Error waiting for CDN Profile (%s) to become available: %s", name, err) -// } -// -// return resourceArmCdnProfileRead(d, meta) -//} -// -//func resourceArmCdnProfileRead(d *schema.ResourceData, meta interface{}) error { -// cdnProfilesClient := meta.(*ArmClient).cdnProfilesClient -// -// id, err := parseAzureResourceID(d.Id()) -// if err != nil { -// return err -// } -// resGroup := id.ResourceGroup -// name := id.Path["Profiles"] -// -// resp, err := cdnProfilesClient.Get(name, resGroup) -// if resp.StatusCode == http.StatusNotFound { -// d.SetId("") -// return nil -// } -// if err != nil { -// return fmt.Errorf("Error making Read request on Azure CDN Profile %s: %s", name, err) -// } -// -// if resp.Properties != nil && resp.Properties.Sku != nil { -// d.Set("sku", string(resp.Properties.Sku.Name)) -// } -// -// flattenAndSetTags(d, resp.Tags) -// -// return nil -//} -// -//func resourceArmCdnProfileUpdate(d *schema.ResourceData, meta interface{}) error { -// cdnProfilesClient := meta.(*ArmClient).cdnProfilesClient -// -// if !d.HasChange("tags") { -// return nil -// } -// -// name := d.Get("name").(string) -// resGroup := d.Get("resource_group_name").(string) -// newTags := d.Get("tags").(map[string]interface{}) -// -// props := cdn.ProfileUpdateParameters{ -// Tags: expandTags(newTags), -// } -// -// _, err := cdnProfilesClient.Update(name, props, resGroup) -// if err != nil { -// return fmt.Errorf("Error issuing Azure ARM update request to update CDN Profile %q: %s", name, err) -// } -// -// return resourceArmCdnProfileRead(d, meta) -//} -// -//func resourceArmCdnProfileDelete(d *schema.ResourceData, meta interface{}) error { -// cdnProfilesClient := meta.(*ArmClient).cdnProfilesClient -// -// id, err := parseAzureResourceID(d.Id()) -// if err != nil { -// return err -// } -// resGroup := id.ResourceGroup -// name := id.Path["Profiles"] -// -// _, err = cdnProfilesClient.DeleteIfExists(name, resGroup) -// -// return err -//} -// -//func cdnProfileStateRefreshFunc(client *ArmClient, resourceGroupName string, cdnProfileName string) resource.StateRefreshFunc { -// return func() (interface{}, string, error) { -// res, err := client.cdnProfilesClient.Get(cdnProfileName, resourceGroupName) -// if err != nil { -// return nil, "", fmt.Errorf("Error issuing read request in cdnProfileStateRefreshFunc to Azure ARM for CND Profile '%s' (RG: '%s'): %s", cdnProfileName, resourceGroupName, err) -// } -// return res, string(res.Properties.ProvisioningState), nil -// } -//} -// -//func validateCdnProfileSku(v interface{}, k string) (ws []string, errors []error) { -// value := strings.ToLower(v.(string)) -// skus := map[string]bool{ -// "standard": true, -// "premium": true, -// } -// -// if !skus[value] { -// errors = append(errors, fmt.Errorf("CDN Profile SKU can only be Standard or Premium")) -// } -// return -//} +import ( + "fmt" + "log" + "net/http" + "strings" + + "github.com/Azure/azure-sdk-for-go/arm/cdn" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceArmCdnProfile() *schema.Resource { + return &schema.Resource{ + Create: resourceArmCdnProfileCreate, + Read: resourceArmCdnProfileRead, + Update: resourceArmCdnProfileUpdate, + Delete: resourceArmCdnProfileDelete, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "location": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + StateFunc: azureRMNormalizeLocation, + }, + + "resource_group_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "sku": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateCdnProfileSku, + }, + + "tags": tagsSchema(), + }, + } +} + +func resourceArmCdnProfileCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient) + cdnProfilesClient := client.cdnProfilesClient + + log.Printf("[INFO] preparing arguments for Azure ARM CDN Profile creation.") + + name := d.Get("name").(string) + location := d.Get("location").(string) + resGroup := d.Get("resource_group_name").(string) + sku := d.Get("sku").(string) + tags := d.Get("tags").(map[string]interface{}) + + properties := cdn.ProfilePropertiesCreateParameters{ + Sku: &cdn.Sku{ + Name: cdn.SkuName(sku), + }, + } + + cdnProfile := cdn.ProfileCreateParameters{ + Location: &location, + Properties: &properties, + Tags: expandTags(tags), + } + + _, err := cdnProfilesClient.Create(name, cdnProfile, resGroup, make(chan struct{})) + if err != nil { + return err + } + + read, err := cdnProfilesClient.Get(name, resGroup) + if err != nil { + return err + } + if read.ID == nil { + return fmt.Errorf("Cannot read CND Profile %s (resource group %s) ID", name, resGroup) + } + + d.SetId(*read.ID) + + return resourceArmCdnProfileRead(d, meta) +} + +func resourceArmCdnProfileRead(d *schema.ResourceData, meta interface{}) error { + cdnProfilesClient := meta.(*ArmClient).cdnProfilesClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["Profiles"] + + resp, err := cdnProfilesClient.Get(name, resGroup) + if resp.StatusCode == http.StatusNotFound { + d.SetId("") + return nil + } + if err != nil { + return fmt.Errorf("Error making Read request on Azure CDN Profile %s: %s", name, err) + } + + if resp.Properties != nil && resp.Properties.Sku != nil { + d.Set("sku", string(resp.Properties.Sku.Name)) + } + + flattenAndSetTags(d, resp.Tags) + + return nil +} + +func resourceArmCdnProfileUpdate(d *schema.ResourceData, meta interface{}) error { + cdnProfilesClient := meta.(*ArmClient).cdnProfilesClient + + if !d.HasChange("tags") { + return nil + } + + name := d.Get("name").(string) + resGroup := d.Get("resource_group_name").(string) + newTags := d.Get("tags").(map[string]interface{}) + + props := cdn.ProfileUpdateParameters{ + Tags: expandTags(newTags), + } + + _, err := cdnProfilesClient.Update(name, props, resGroup) + if err != nil { + return fmt.Errorf("Error issuing Azure ARM update request to update CDN Profile %q: %s", name, err) + } + + return resourceArmCdnProfileRead(d, meta) +} + +func resourceArmCdnProfileDelete(d *schema.ResourceData, meta interface{}) error { + cdnProfilesClient := meta.(*ArmClient).cdnProfilesClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["Profiles"] + + _, err = cdnProfilesClient.DeleteIfExists(name, resGroup, make(chan struct{})) + + return err +} + +func validateCdnProfileSku(v interface{}, k string) (ws []string, errors []error) { + value := strings.ToLower(v.(string)) + skus := map[string]bool{ + "standard": true, + "premium": true, + } + + if !skus[value] { + errors = append(errors, fmt.Errorf("CDN Profile SKU can only be Standard or Premium")) + } + return +} diff --git a/builtin/providers/azurerm/resource_arm_cdn_profile_test.go b/builtin/providers/azurerm/resource_arm_cdn_profile_test.go index c72c560b2..aa16dbe21 100644 --- a/builtin/providers/azurerm/resource_arm_cdn_profile_test.go +++ b/builtin/providers/azurerm/resource_arm_cdn_profile_test.go @@ -1,207 +1,207 @@ package azurerm -//import ( -// "fmt" -// "net/http" -// "testing" -// -// "github.com/hashicorp/terraform/helper/acctest" -// "github.com/hashicorp/terraform/helper/resource" -// "github.com/hashicorp/terraform/terraform" -//) -// -//func TestResourceAzureRMCdnProfileSKU_validation(t *testing.T) { -// cases := []struct { -// Value string -// ErrCount int -// }{ -// { -// Value: "Random", -// ErrCount: 1, -// }, -// { -// Value: "Standard", -// ErrCount: 0, -// }, -// { -// Value: "Premium", -// ErrCount: 0, -// }, -// { -// Value: "STANDARD", -// ErrCount: 0, -// }, -// { -// Value: "PREMIUM", -// ErrCount: 0, -// }, -// } -// -// for _, tc := range cases { -// _, errors := validateCdnProfileSku(tc.Value, "azurerm_cdn_profile") -// -// if len(errors) != tc.ErrCount { -// t.Fatalf("Expected the Azure RM CDN Profile SKU to trigger a validation error") -// } -// } -//} -// -//func TestAccAzureRMCdnProfile_basic(t *testing.T) { -// -// ri := acctest.RandInt() -// config := fmt.Sprintf(testAccAzureRMCdnProfile_basic, ri, ri) -// -// resource.Test(t, resource.TestCase{ -// PreCheck: func() { testAccPreCheck(t) }, -// Providers: testAccProviders, -// CheckDestroy: testCheckAzureRMCdnProfileDestroy, -// Steps: []resource.TestStep{ -// resource.TestStep{ -// Config: config, -// Check: resource.ComposeTestCheckFunc( -// testCheckAzureRMCdnProfileExists("azurerm_cdn_profile.test"), -// ), -// }, -// }, -// }) -//} -// -//func TestAccAzureRMCdnProfile_withTags(t *testing.T) { -// -// ri := acctest.RandInt() -// preConfig := fmt.Sprintf(testAccAzureRMCdnProfile_withTags, ri, ri) -// postConfig := fmt.Sprintf(testAccAzureRMCdnProfile_withTagsUpdate, ri, ri) -// -// resource.Test(t, resource.TestCase{ -// PreCheck: func() { testAccPreCheck(t) }, -// Providers: testAccProviders, -// CheckDestroy: testCheckAzureRMCdnProfileDestroy, -// Steps: []resource.TestStep{ -// resource.TestStep{ -// Config: preConfig, -// Check: resource.ComposeTestCheckFunc( -// testCheckAzureRMCdnProfileExists("azurerm_cdn_profile.test"), -// resource.TestCheckResourceAttr( -// "azurerm_cdn_profile.test", "tags.#", "2"), -// resource.TestCheckResourceAttr( -// "azurerm_cdn_profile.test", "tags.environment", "Production"), -// resource.TestCheckResourceAttr( -// "azurerm_cdn_profile.test", "tags.cost_center", "MSFT"), -// ), -// }, -// -// resource.TestStep{ -// Config: postConfig, -// Check: resource.ComposeTestCheckFunc( -// testCheckAzureRMCdnProfileExists("azurerm_cdn_profile.test"), -// resource.TestCheckResourceAttr( -// "azurerm_cdn_profile.test", "tags.#", "1"), -// resource.TestCheckResourceAttr( -// "azurerm_cdn_profile.test", "tags.environment", "staging"), -// ), -// }, -// }, -// }) -//} -// -//func testCheckAzureRMCdnProfileExists(name string) resource.TestCheckFunc { -// return func(s *terraform.State) error { -// // Ensure we have enough information in state to look up in API -// rs, ok := s.RootModule().Resources[name] -// if !ok { -// return fmt.Errorf("Not found: %s", name) -// } -// -// name := rs.Primary.Attributes["name"] -// resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] -// if !hasResourceGroup { -// return fmt.Errorf("Bad: no resource group found in state for cdn profile: %s", name) -// } -// -// conn := testAccProvider.Meta().(*ArmClient).cdnProfilesClient -// -// resp, err := conn.Get(name, resourceGroup) -// if err != nil { -// return fmt.Errorf("Bad: Get on cdnProfilesClient: %s", err) -// } -// -// if resp.StatusCode == http.StatusNotFound { -// return fmt.Errorf("Bad: CDN Profile %q (resource group: %q) does not exist", name, resourceGroup) -// } -// -// return nil -// } -//} -// -//func testCheckAzureRMCdnProfileDestroy(s *terraform.State) error { -// conn := testAccProvider.Meta().(*ArmClient).cdnProfilesClient -// -// for _, rs := range s.RootModule().Resources { -// if rs.Type != "azurerm_cdn_profile" { -// continue -// } -// -// name := rs.Primary.Attributes["name"] -// resourceGroup := rs.Primary.Attributes["resource_group_name"] -// -// resp, err := conn.Get(name, resourceGroup) -// -// if err != nil { -// return nil -// } -// -// if resp.StatusCode != http.StatusNotFound { -// return fmt.Errorf("CDN Profile still exists:\n%#v", resp.Properties) -// } -// } -// -// return nil -//} -// -//var testAccAzureRMCdnProfile_basic = ` -//resource "azurerm_resource_group" "test" { -// name = "acctestrg-%d" -// location = "West US" -//} -//resource "azurerm_cdn_profile" "test" { -// name = "acctestcdnprof%d" -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -// sku = "Standard" -//} -//` -// -//var testAccAzureRMCdnProfile_withTags = ` -//resource "azurerm_resource_group" "test" { -// name = "acctestrg-%d" -// location = "West US" -//} -//resource "azurerm_cdn_profile" "test" { -// name = "acctestcdnprof%d" -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -// sku = "Standard" -// -// tags { -// environment = "Production" -// cost_center = "MSFT" -// } -//} -//` -// -//var testAccAzureRMCdnProfile_withTagsUpdate = ` -//resource "azurerm_resource_group" "test" { -// name = "acctestrg-%d" -// location = "West US" -//} -//resource "azurerm_cdn_profile" "test" { -// name = "acctestcdnprof%d" -// location = "West US" -// resource_group_name = "${azurerm_resource_group.test.name}" -// sku = "Standard" -// -// tags { -// environment = "staging" -// } -//} -//` +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestResourceAzureRMCdnProfileSKU_validation(t *testing.T) { + cases := []struct { + Value string + ErrCount int + }{ + { + Value: "Random", + ErrCount: 1, + }, + { + Value: "Standard", + ErrCount: 0, + }, + { + Value: "Premium", + ErrCount: 0, + }, + { + Value: "STANDARD", + ErrCount: 0, + }, + { + Value: "PREMIUM", + ErrCount: 0, + }, + } + + for _, tc := range cases { + _, errors := validateCdnProfileSku(tc.Value, "azurerm_cdn_profile") + + if len(errors) != tc.ErrCount { + t.Fatalf("Expected the Azure RM CDN Profile SKU to trigger a validation error") + } + } +} + +func TestAccAzureRMCdnProfile_basic(t *testing.T) { + + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMCdnProfile_basic, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCdnProfileDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMCdnProfileExists("azurerm_cdn_profile.test"), + ), + }, + }, + }) +} + +func TestAccAzureRMCdnProfile_withTags(t *testing.T) { + + ri := acctest.RandInt() + preConfig := fmt.Sprintf(testAccAzureRMCdnProfile_withTags, ri, ri) + postConfig := fmt.Sprintf(testAccAzureRMCdnProfile_withTagsUpdate, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCdnProfileDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMCdnProfileExists("azurerm_cdn_profile.test"), + resource.TestCheckResourceAttr( + "azurerm_cdn_profile.test", "tags.#", "2"), + resource.TestCheckResourceAttr( + "azurerm_cdn_profile.test", "tags.environment", "Production"), + resource.TestCheckResourceAttr( + "azurerm_cdn_profile.test", "tags.cost_center", "MSFT"), + ), + }, + + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMCdnProfileExists("azurerm_cdn_profile.test"), + resource.TestCheckResourceAttr( + "azurerm_cdn_profile.test", "tags.#", "1"), + resource.TestCheckResourceAttr( + "azurerm_cdn_profile.test", "tags.environment", "staging"), + ), + }, + }, + }) +} + +func testCheckAzureRMCdnProfileExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for cdn profile: %s", name) + } + + conn := testAccProvider.Meta().(*ArmClient).cdnProfilesClient + + resp, err := conn.Get(name, resourceGroup) + if err != nil { + return fmt.Errorf("Bad: Get on cdnProfilesClient: %s", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: CDN Profile %q (resource group: %q) does not exist", name, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMCdnProfileDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).cdnProfilesClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_cdn_profile" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(name, resourceGroup) + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("CDN Profile still exists:\n%#v", resp.Properties) + } + } + + return nil +} + +var testAccAzureRMCdnProfile_basic = ` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "West US" +} +resource "azurerm_cdn_profile" "test" { + name = "acctestcdnprof%d" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" +} +` + +var testAccAzureRMCdnProfile_withTags = ` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "West US" +} +resource "azurerm_cdn_profile" "test" { + name = "acctestcdnprof%d" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + + tags { + environment = "Production" + cost_center = "MSFT" + } +} +` + +var testAccAzureRMCdnProfile_withTagsUpdate = ` +resource "azurerm_resource_group" "test" { + name = "acctestrg-%d" + location = "West US" +} +resource "azurerm_cdn_profile" "test" { + name = "acctestcdnprof%d" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "Standard" + + tags { + environment = "staging" + } +} +`