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  }