github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/azurerm/resource_arm_cdn_endpoint.go (about)

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