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