github.com/ottenhoff/terraform@v0.7.0-rc1.0.20160607213102-ac2d195cc560/builtin/providers/azurerm/resource_arm_cdn_endpoint.go (about)

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