diff --git a/bigip/provider.go b/bigip/provider.go index d49ea16a3..d31d28ec3 100644 --- a/bigip/provider.go +++ b/bigip/provider.go @@ -126,6 +126,7 @@ func Provider() *schema.Provider { "bigip_ltm_profile_tcp": resourceBigipLtmProfileTcp(), "bigip_ltm_profile_ftp": resourceBigipLtmProfileFtp(), "bigip_ltm_profile_http": resourceBigipLtmProfileHttp(), + "bigip_ltm_profile_web_acceleration": resourceBigipLtmProfileWebAcceleration(), "bigip_ltm_persistence_profile_srcaddr": resourceBigipLtmPersistenceProfileSrcAddr(), "bigip_ltm_persistence_profile_dstaddr": resourceBigipLtmPersistenceProfileDstAddr(), "bigip_ltm_persistence_profile_ssl": resourceBigipLtmPersistenceProfileSSL(), diff --git a/bigip/resource_bigip_ltm_profile_web_acceleration.go b/bigip/resource_bigip_ltm_profile_web_acceleration.go new file mode 100644 index 000000000..7e73ef223 --- /dev/null +++ b/bigip/resource_bigip_ltm_profile_web_acceleration.go @@ -0,0 +1,280 @@ +/* +Copyright 2019 F5 Networks Inc. +This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ +package bigip + +import ( + "context" + "log" + "os" + "strings" + + bigip "github.com/f5devcentral/go-bigip" + "github.com/f5devcentral/go-bigip/f5teem" + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceBigipLtmProfileWebAcceleration() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceBigipLtmProfileWebAccelerationCreate, + ReadContext: resourceBigipLtmProfileWebAccelerationRead, + UpdateContext: resourceBigipLtmProfileWebAccelerationUpdate, + DeleteContext: resourceBigipLtmProfileWebAccelerationDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Name of the Web Acceleration profile", + ValidateFunc: validateF5NameWithDirectory, + }, + "defaults_from": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Specifies the profile that you want to use as the parent profile. Your new profile inherits all settings and values from the parent profile specified.", + ValidateFunc: validateF5Name, + }, + "cache_size": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Specifies the maximum size for the cache. When the cache reaches the maximum size, the system starts removing the oldest entries. The default value is 100 megabytes.", + }, + "cache_max_entries": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Specifies the maximum number of entries that can be in the cache. The default value is 0 (zero), which means that the system does not limit the maximum entries.", + }, + "cache_max_age": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Specifies how long the system considers the cached content to be valid. The default value is 3600 seconds.", + }, + "cache_object_min_size": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Specifies the smallest object that the system considers eligible for caching. The default value is 500 bytes.", + }, + "cache_object_max_size": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Specifies the largest object that the system considers eligible for caching. The default value is 50000 bytes.", + }, + "cache_uri_exclude": { + Type: schema.TypeSet, + Set: schema.HashString, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + Computed: true, + Description: "Configures a list of URIs to exclude from the cache. The default value of none specifies no URIs are excluded.", + }, + "cache_uri_include": { + Type: schema.TypeSet, + Set: schema.HashString, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + Computed: true, + Description: "Configures a list of URIs to include in the cache. The default value of .* specifies that all URIs are cacheable.", + }, + "cache_uri_include_override": { + Type: schema.TypeSet, + Set: schema.HashString, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + Computed: true, + Description: "Configures a list of URIs to include in the cache even if they would normally be excluded due to factors like object size or HTTP request type. The default value of none specifies no URIs are to be forced into the cache.", + }, + "cache_uri_pinned": { + Type: schema.TypeSet, + Set: schema.HashString, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + Computed: true, + Description: "Configures a list of URIs to keep in the cache. The pinning process keeps URIs in cache when they would normally be evicted to make room for more active URIs.", + }, + "cache_client_cache_control_mode": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Specifies which cache disabling headers sent by clients the system ignores. The default value is all.", + }, + "cache_insert_age_header": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Inserts Age and Date headers in the response. The default value is enabled.", + }, + "cache_aging_rate": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "Specifies how quickly the system ages a cache entry. The aging rate ranges from 0 (slowest aging) to 10 (fastest aging). The default value is 9.", + }, + }, + } +} + +func resourceBigipLtmProfileWebAccelerationCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + + name := d.Get("name").(string) + log.Printf("[INFO] Creating Profile Web Acceleration Service:%+v ", name) + + pss := &bigip.WebAccelerationProfileService{ + Name: name, + } + config := getHttpProfileWebAccelerationConfig(d, pss) + + err := client.AddWebAcceleration(config) + if err != nil { + return diag.FromErr(err) + } + d.SetId(name) + + if !client.Teem { + id := uuid.New() + uniqueID := id.String() + assetInfo := f5teem.AssetInfo{ + Name: "Terraform-provider-bigip", + Version: client.UserAgent, + Id: uniqueID, + } + apiKey := os.Getenv("TEEM_API_KEY") + teemDevice := f5teem.AnonymousClient(assetInfo, apiKey) + f := map[string]interface{}{ + "Terraform Version": client.UserAgent, + } + tsVer := strings.Split(client.UserAgent, "/") + err = teemDevice.Report(f, "bigip_ltm_profile_web_acceleration", tsVer[3]) + if err != nil { + log.Printf("[ERROR]Sending Telemetry data failed:%v", err) + } + } + return resourceBigipLtmProfileWebAccelerationRead(ctx, d, meta) +} + +func resourceBigipLtmProfileWebAccelerationRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + + name := d.Id() + + log.Println("[INFO] Fetching HTTP Profile Web Acceleration" + name) + + wap, err := client.GetWebAccelerationProfile(name) + + if err != nil { + log.Printf("[ERROR] Unable to retrieve Profile Web Acceleration (%s) ", err) + return diag.FromErr(err) + } + if wap == nil { + log.Printf("[WARN] Web Acceleration Profile (%s) not found, removing from state", name) + d.SetId("") + return nil + } + _ = d.Set("name", name) + _ = d.Set("defaults_from", wap.DefaultsFrom) + + if _, ok := d.GetOk("cache_size"); ok { + _ = d.Set("cache_size", wap.CacheSize) + } + if _, ok := d.GetOk("cache_max_entries"); ok { + _ = d.Set("cache_max_entries", wap.CacheMaxEntries) + } + if _, ok := d.GetOk("cache_max_age"); ok { + _ = d.Set("cache_max_age", wap.CacheMaxAge) + } + if _, ok := d.GetOk("cache_object_min_size"); ok { + _ = d.Set("cache_object_min_size", wap.CacheObjectMinSize) + } + if _, ok := d.GetOk("cache_object_max_size"); ok { + _ = d.Set("cache_object_max_size", wap.CacheObjectMaxSize) + } + if _, ok := d.GetOk("cache_uri_exclude"); ok { + _ = d.Set("cache_uri_exclude", wap.CacheUriExclude) + } + if _, ok := d.GetOk("cache_uri_include"); ok { + _ = d.Set("cache_uri_include", wap.CacheUriInclude) + } + if _, ok := d.GetOk("cache_uri_include_override"); ok { + _ = d.Set("cache_uri_include_override", wap.CacheUriIncludeOverride) + } + if _, ok := d.GetOk("cache_uri_pinned"); ok { + _ = d.Set("cache_uri_pinned", wap.CacheUriPinned) + } + if _, ok := d.GetOk("cache_client_cache_control_mode"); ok { + _ = d.Set("cache_client_cache_control_mode", wap.CacheClientCacheControlMode) + } + if _, ok := d.GetOk("cache_insert_age_header"); ok { + _ = d.Set("cache_insert_age_header", wap.CacheInsertAgeHeader) + } + if _, ok := d.GetOk("cache_aging_rate"); ok { + _ = d.Set("cache_aging_rate", wap.CacheAgingRate) + } + + return nil +} + +func resourceBigipLtmProfileWebAccelerationUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + name := d.Id() + log.Printf("[INFO] Updating Profile Web Acceleration:%+v ", name) + + pss := &bigip.WebAccelerationProfileService{ + Name: name, + } + config := getHttpProfileWebAccelerationConfig(d, pss) + + err := client.ModifyWebAccelerationProfile(name, config) + + if err != nil { + log.Printf("[ERROR] Unable to Modify HTTP Profile (%s) (%v)", name, err) + return diag.FromErr(err) + } + + return resourceBigipLtmProfileWebAccelerationRead(ctx, d, meta) + +} + +func resourceBigipLtmProfileWebAccelerationDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + + name := d.Id() + log.Println("[INFO] Deleting Profile Web Acceleration " + name) + err := client.DeleteWebAccelerationProfile(name) + if err != nil { + log.Printf("[ERROR] Unable to Delete Profile Web Acceleration (%s) (%v) ", name, err) + return diag.FromErr(err) + } + d.SetId("") + return nil +} + +func getHttpProfileWebAccelerationConfig(d *schema.ResourceData, config *bigip.WebAccelerationProfileService) *bigip.WebAccelerationProfileService { + config.DefaultsFrom = d.Get("defaults_from").(string) + config.CacheSize = d.Get("cache_size").(int) + config.CacheMaxEntries = d.Get("cache_max_entries").(int) + config.CacheMaxAge = d.Get("cache_max_age").(int) + config.CacheObjectMinSize = d.Get("cache_object_min_size").(int) + config.CacheObjectMaxSize = d.Get("cache_object_max_size").(int) + config.CacheUriExclude = setToStringSlice(d.Get("cache_uri_exclude").(*schema.Set)) + config.CacheUriInclude = setToStringSlice(d.Get("cache_uri_include").(*schema.Set)) + config.CacheUriIncludeOverride = setToStringSlice(d.Get("cache_uri_include_override").(*schema.Set)) + config.CacheUriPinned = setToStringSlice(d.Get("cache_uri_pinned").(*schema.Set)) + config.CacheClientCacheControlMode = d.Get("cache_client_cache_control_mode").(string) + config.CacheInsertAgeHeader = d.Get("cache_insert_age_header").(string) + config.CacheAgingRate = d.Get("cache_aging_rate").(int) + + return config +} diff --git a/bigip/resource_bigip_ltm_profile_web_acceleration_test.go b/bigip/resource_bigip_ltm_profile_web_acceleration_test.go new file mode 100644 index 000000000..502c08eb7 --- /dev/null +++ b/bigip/resource_bigip_ltm_profile_web_acceleration_test.go @@ -0,0 +1,575 @@ +/* +Copyright 2019 F5 Networks Inc. +This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ +package bigip + +import ( + "fmt" + "regexp" + "testing" + + bigip "github.com/f5devcentral/go-bigip" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +var TestWebAccelerationName = fmt.Sprintf("/%s/test", TestPartition) +var resWebAccelerationName = "bigip_ltm_profile_web_acceleration" + +var TestWebAccelerationResource = ` +resource "bigip_ltm_profile_web_acceleration" "web_acceleration" { + name = "/Common/web_acceleration" + defaults_from = "/Common/webacceleration" +} +` + +func TestAccBigipLtmWebAccelerationProfileCreate(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckWebAccelerationDestroyed, + Steps: []resource.TestStep{ + { + Config: TestWebAccelerationResource, + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(TestWebAccelerationName), + resource.TestCheckResourceAttr("bigip_ltm_profile_web_acceleration.web_acceleration", "name", "/Common/web_acceleration"), + resource.TestCheckResourceAttr("bigip_ltm_profile_web_acceleration.web_acceleration", "defaults_from", "/Common/webacceleration"), + ), + }, + }, + }) +} + +func TestAccBigipLtmWebAccelerationProfileCreateFail(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckWebAccelerationDestroyed, + Steps: []resource.TestStep{ + { + Config: TestWebAccelerationResource, + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(TestWebAccelerationName), + resource.TestCheckResourceAttr("bigip_ltm_profile_web_acceleration.web_acceleration", "name", "/Common/web_acceleration"), + resource.TestCheckResourceAttr("bigip_ltm_profile_web_acceleration.web_acceleration", "defaults_from", "/Common/web_acceleration"), + ), + ExpectError: regexp.MustCompile("Attribute 'defaults_from' expected"), + }, + }, + }) +} + +func TestAccBigipLtmWebAccelerationProfileUpdateCacheSize(t *testing.T) { + t.Parallel() + var instName = "web_acceleration-Update-CacheSize" + var instFullName = fmt.Sprintf("/%s/%s", TestPartition, instName) + resFullName := fmt.Sprintf("%s.%s", resWebAccelerationName, instName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckWebAccelerationDestroyed, + Steps: []resource.TestStep{ + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, ""), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + ), + }, + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, "cache_size"), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + resource.TestCheckResourceAttr(resFullName, "cache_size", "100"), + ), + }, + }, + }) +} +func TestAccBigipLtmWebAccelerationProfileUpdateCacheMaxEntries(t *testing.T) { + t.Parallel() + var instName = "web_acceleration-Update-CacheMaxEntries" + var instFullName = fmt.Sprintf("/%s/%s", TestPartition, instName) + resFullName := fmt.Sprintf("%s.%s", resWebAccelerationName, instName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckWebAccelerationDestroyed, + Steps: []resource.TestStep{ + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, ""), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + ), + }, + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, "cache_max_entries"), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + resource.TestCheckResourceAttr(resFullName, "cache_max_entries", "201"), + ), + }, + }, + }) +} + +func TestAccBigipLtmWebAccelerationProfileUpdateCacheMaxAge(t *testing.T) { + t.Parallel() + var instName = "web_acceleration-Update-CacheMaxAge" + var instFullName = fmt.Sprintf("/%s/%s", TestPartition, instName) + resFullName := fmt.Sprintf("%s.%s", resWebAccelerationName, instName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckWebAccelerationDestroyed, + Steps: []resource.TestStep{ + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, ""), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + ), + }, + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, "cache_max_age"), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + resource.TestCheckResourceAttr(resFullName, "cache_max_age", "301"), + ), + }, + }, + }) +} + +func TestAccBigipLtmWebAccelerationProfileUpdateCacheObjectMinSize(t *testing.T) { + t.Parallel() + var instName = "web_acceleration-Update-CacheObjectMinSize" + var instFullName = fmt.Sprintf("/%s/%s", TestPartition, instName) + resFullName := fmt.Sprintf("%s.%s", resWebAccelerationName, instName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckWebAccelerationDestroyed, + Steps: []resource.TestStep{ + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, ""), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + ), + }, + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, "cache_object_min_size"), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + resource.TestCheckResourceAttr(resFullName, "cache_object_min_size", "501"), + ), + }, + }, + }) +} + +func TestAccBigipLtmWebAccelerationProfileUpdateCacheObjectMaxSize(t *testing.T) { + t.Parallel() + var instName = "web_acceleration-Update-CacheObjectMaxSize" + var instFullName = fmt.Sprintf("/%s/%s", TestPartition, instName) + resFullName := fmt.Sprintf("%s.%s", resWebAccelerationName, instName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckWebAccelerationDestroyed, + Steps: []resource.TestStep{ + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, ""), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + ), + }, + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, "cache_object_max_size"), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + resource.TestCheckResourceAttr(resFullName, "cache_object_max_size", "502"), + ), + }, + }, + }) +} + +func TestAccBigipLtmWebAccelerationProfileUpdateCacheUriExclude(t *testing.T) { + t.Parallel() + var instName = "web_acceleration-Update-CacheUriExclude" + var instFullName = fmt.Sprintf("/%s/%s", TestPartition, instName) + resFullName := fmt.Sprintf("%s.%s", resWebAccelerationName, instName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckWebAccelerationDestroyed, + Steps: []resource.TestStep{ + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, ""), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + ), + }, + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, "cache_uri_exclude"), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + resource.TestCheckTypeSetElemAttr(resFullName, "cache_uri_exclude.*", "exclude"), + ), + }, + }, + }) +} + +func TestAccBigipLtmWebAccelerationProfileUpdateCacheUriInclude(t *testing.T) { + t.Parallel() + var instName = "web_acceleration-Update-CacheUriInclude" + var instFullName = fmt.Sprintf("/%s/%s", TestPartition, instName) + resFullName := fmt.Sprintf("%s.%s", resWebAccelerationName, instName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckWebAccelerationDestroyed, + Steps: []resource.TestStep{ + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, ""), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + ), + }, + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, "cache_uri_include"), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + resource.TestCheckTypeSetElemAttr(resFullName, "cache_uri_include.*", "include"), + ), + }, + }, + }) +} + +func TestAccBigipLtmWebAccelerationProfileUpdateCacheUriIncludeOverride(t *testing.T) { + t.Parallel() + var instName = "web_acceleration-Update-CacheUriIncludeOverride" + var instFullName = fmt.Sprintf("/%s/%s", TestPartition, instName) + resFullName := fmt.Sprintf("%s.%s", resWebAccelerationName, instName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckWebAccelerationDestroyed, + Steps: []resource.TestStep{ + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, ""), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + ), + }, + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, "cache_uri_include_override"), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + resource.TestCheckTypeSetElemAttr(resFullName, "cache_uri_include_override.*", "include_override"), + ), + }, + }, + }) +} + +func TestAccBigipLtmWebAccelerationProfileUpdateCacheUriPinned(t *testing.T) { + t.Parallel() + var instName = "web_acceleration-Update-CacheUriPinned" + var instFullName = fmt.Sprintf("/%s/%s", TestPartition, instName) + resFullName := fmt.Sprintf("%s.%s", resWebAccelerationName, instName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckWebAccelerationDestroyed, + Steps: []resource.TestStep{ + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, ""), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + ), + }, + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, "cache_uri_pinned"), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + resource.TestCheckTypeSetElemAttr(resFullName, "cache_uri_pinned.*", "pinned"), + ), + }, + }, + }) +} + +func TestAccBigipLtmWebAccelerationProfileUpdateCacheClientCacheControlMode(t *testing.T) { + t.Parallel() + var instName = "web_acceleration-Update-CacheClientCacheControlMode" + var instFullName = fmt.Sprintf("/%s/%s", TestPartition, instName) + resFullName := fmt.Sprintf("%s.%s", resWebAccelerationName, instName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckWebAccelerationDestroyed, + Steps: []resource.TestStep{ + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, ""), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + ), + }, + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, "cache_client_cache_control_mode"), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + resource.TestCheckResourceAttr(resFullName, "cache_client_cache_control_mode", "all"), + ), + }, + }, + }) +} + +func TestAccBigipLtmWebAccelerationProfileUpdateCacheInsertAgeHeader(t *testing.T) { + t.Parallel() + var instName = "web_acceleration-Update-CacheInsertAgeHeader" + var instFullName = fmt.Sprintf("/%s/%s", TestPartition, instName) + resFullName := fmt.Sprintf("%s.%s", resWebAccelerationName, instName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckWebAccelerationDestroyed, + Steps: []resource.TestStep{ + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, ""), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + ), + }, + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, "cache_insert_age_header"), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + resource.TestCheckResourceAttr(resFullName, "cache_insert_age_header", "disabled"), + ), + }, + }, + }) +} + +func TestAccBigipLtmWebAccelerationProfileUpdateCacheAgingRate(t *testing.T) { + t.Parallel() + var instName = "web_acceleration-Update-CacheAgingRate" + var instFullName = fmt.Sprintf("/%s/%s", TestPartition, instName) + resFullName := fmt.Sprintf("%s.%s", resWebAccelerationName, instName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckWebAccelerationDestroyed, + Steps: []resource.TestStep{ + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, ""), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + ), + }, + { + Config: testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, "cache_aging_rate"), + Check: resource.ComposeTestCheckFunc( + testCheckWebAccelerationExists(instFullName), + resource.TestCheckResourceAttr(resFullName, "name", instFullName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/webacceleration"), + resource.TestCheckResourceAttr(resFullName, "cache_aging_rate", "9"), + ), + }, + }, + }) +} + +func TestAccBigipLtmWebAccelerationProfileImport(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckWebAccelerationDestroyed, + Steps: []resource.TestStep{ + { + Config: testaccBigipLtmWebAccelerationProfileImportConfig(), + }, + { + ResourceName: "bigip_ltm_profile_web_acceleration.test-web-acceleration", + ImportStateId: "/Common/test-web-acceleration", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCheckWebAccelerationExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*bigip.BigIP) + p, err := client.GetWebAccelerationProfile(name) + if err != nil { + return err + } + if p == nil { + return fmt.Errorf("web acceleration %s was not created", name) + } + + return nil + } +} + +func testCheckWebAccelerationDestroyed(s *terraform.State) error { + client := testAccProvider.Meta().(*bigip.BigIP) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "bigip_ltm_profile_web_acceleration" { + continue + } + + name := rs.Primary.ID + http, err := client.GetWebAccelerationProfile(name) + if err != nil { + return err + } + if http != nil { + return fmt.Errorf("web acceleration %s not destroyed ", name) + } + } + return nil +} + +func testaccBigipLtmWebAccelerationProfileImportConfig() string { + return fmt.Sprintf(` +resource "bigip_ltm_profile_web_acceleration" "test-web-acceleration" { + name = "%s" + defaults_from = "/Common/webacceleration" +} +`, "/Common/test-web-acceleration") +} + +func testAccBigipLtmWebAccelerationProfileDefaultConfig(instName, updateParam string) string { + resPrefix := fmt.Sprintf(` + resource "%[1]s" "%[2]s" { + name = "/Common/%[2]s" + defaults_from = "/Common/webacceleration"`, resWebAccelerationName, instName) + switch updateParam { + case "cache_size": + resPrefix = fmt.Sprintf(`%s + cache_size = 100`, resPrefix) + case "cache_max_entries": + resPrefix = fmt.Sprintf(`%s + cache_max_entries = 201`, resPrefix) + case "cache_max_age": + resPrefix = fmt.Sprintf(`%s + cache_max_age = 301`, resPrefix) + case "cache_object_min_size": + resPrefix = fmt.Sprintf(`%s + cache_object_min_size = 501`, resPrefix) + case "cache_object_max_size": + resPrefix = fmt.Sprintf(`%s + cache_object_max_size = 502`, resPrefix) + case "cache_uri_exclude": + resPrefix = fmt.Sprintf(`%s + cache_uri_exclude = ["exclude"]`, resPrefix) + case "cache_uri_include": + resPrefix = fmt.Sprintf(`%s + cache_uri_include = ["include"]`, resPrefix) + case "cache_uri_include_override": + resPrefix = fmt.Sprintf(`%s + cache_uri_include_override = ["include_override"]`, resPrefix) + case "cache_uri_pinned": + resPrefix = fmt.Sprintf(`%s + cache_uri_pinned = ["pinned"]`, resPrefix) + case "cache_client_cache_control_mode": + resPrefix = fmt.Sprintf(`%s + cache_client_cache_control_mode = "all"`, resPrefix) + case "cache_insert_age_header": + resPrefix = fmt.Sprintf(`%s + cache_insert_age_header = "disabled"`, resPrefix) + case "cache_aging_rate": + resPrefix = fmt.Sprintf(`%s + cache_aging_rate = 9`, resPrefix) + default: + } + return fmt.Sprintf(`%s + }`, resPrefix) +} diff --git a/docs/resources/bigip_ltm_profile_web_acceleration.md b/docs/resources/bigip_ltm_profile_web_acceleration.md new file mode 100644 index 000000000..7fbf958ca --- /dev/null +++ b/docs/resources/bigip_ltm_profile_web_acceleration.md @@ -0,0 +1,55 @@ +--- +layout: "bigip" +page_title: "BIG-IP: bigip_ltm_profile_web_acceleration" +subcategory: "Local Traffic Manager(LTM)" +description: |- + Provides details about bigip_ltm_profile_web_acceleration resource +--- + +# bigip\_ltm\_profile_web_acceleration + +`bigip_ltm_profile_web_acceleration` Configures a custom web-acceleration profile for use. + +For resources should be named with their "full path". The full path is the combination of the partition + name of the resource. For example /Common/sample-resource. + +## Example Usage + + +```hcl +resource "bigip_ltm_profile_web_acceleration" "sample-resource" { + name = "/Common/sample-resource" + defaults_from = "/Common/test2" + cache_size = 101 + cache_max_entries = 201 +} +``` + +## Argument Reference + +* `name` (Required,type `string`) Specifies the name of the web acceleration profile service ,name of Profile should be full path. Full path is the combination of the `partition + web acceleration profile name`,For example `/Common/sample-resource`. + +* `defaults_from` - (optional,type `string`) Specifies the profile that you want to use as the parent profile. Your new profile inherits all settings and values from the parent profile specified. + +* `cache_size` - (optional,type `int`) Specifies the maximum size for the cache. When the cache reaches the maximum size, the system starts removing the oldest entries. The default value is `100 megabytes`. + +* `cache_max_entries` - (Optional, type `int`) Specifies the maximum number of entries that can be in the cache. The default value is `0` (zero), which means that the system does not limit the maximum entries. + +* `cache_max_age` - (Optional, type `int`) Specifies how long the system considers the cached content to be valid. The default value is `3600 seconds`. + +* `cache_object_min_size` - (Optional,type `int`) Specifies the smallest object that the system considers eligible for caching. The default value is `500 bytes`. + +* `cache_object_max_size` - (Optional, type `int`) Specifies the smallest object that the system considers eligible for caching. The default value is `500 bytes`. + +* `cache_uri_exclude` - (Optional,type `list`) Configures a list of URIs to exclude from the cache. The default value of `none` specifies no URIs are excluded. + +* `cache_uri_include` - (Optional,type `list`) Configures a list of URIs to include in the cache. The default value of `.*` specifies that all URIs are cacheable. + +* `cache_uri_include_override` - (Optional,type `list`) Configures a list of URIs to include in the cache even if they would normally be excluded due to factors like object size or HTTP request type. The default value of none specifies no URIs are to be forced into the cache. + +* `cache_uri_pinned` - (Optional,type `list`) Configures a list of URIs to keep in the cache. The pinning process keeps URIs in cache when they would normally be evicted to make room for more active URIs. + +* `cache_client_cache_control_mode` - (Optional, type `string`) Specifies which cache disabling headers sent by clients the system ignores. The default value is `all`. + +* `cache_insert_age_header` - (Optional, type `string`) Inserts Age and Date headers in the response. The default value is `enabled`. + +* `cache_aging_rate` - (Optional,type `int`) Specifies how quickly the system ages a cache entry. The aging rate ranges from 0 (slowest aging) to 10 (fastest aging). The default value is `9`. diff --git a/vendor/github.com/f5devcentral/go-bigip/gtm.go b/vendor/github.com/f5devcentral/go-bigip/gtm.go index b106147c6..c764c9d63 100644 --- a/vendor/github.com/f5devcentral/go-bigip/gtm.go +++ b/vendor/github.com/f5devcentral/go-bigip/gtm.go @@ -144,6 +144,7 @@ const ( uriGtmmonitor = "monitor" uriHttp = "http" uriPool_a = "pool/a" + uriWebAcceleration = "web-acceleration" ) func (b *BigIP) Datacenters() (*Datacenter, error) { diff --git a/vendor/github.com/f5devcentral/go-bigip/ltm.go b/vendor/github.com/f5devcentral/go-bigip/ltm.go index 5530761d3..1f362bf3f 100644 --- a/vendor/github.com/f5devcentral/go-bigip/ltm.go +++ b/vendor/github.com/f5devcentral/go-bigip/ltm.go @@ -1809,35 +1809,35 @@ type HttpProfiles struct { } type HttpProfile struct { - AcceptXff string `json:"acceptXff,omitempty"` - AppService string `json:"appService,omitempty"` - BasicAuthRealm string `json:"basicAuthRealm,omitempty"` - DefaultsFrom string `json:"defaultsFrom,omitempty"` - Description string `json:"description,omitempty"` - EncryptCookieSecret string `json:"encryptCookieSecret,omitempty"` - EncryptCookies []string `json:"encryptCookies,omitempty"` - FallbackHost string `json:"fallbackHost,omitempty"` - FallbackStatusCodes []string `json:"fallbackStatusCodes,omitempty"` - HeaderErase string `json:"headerErase,omitempty"` - HeaderInsert string `json:"headerInsert,omitempty"` - InsertXforwardedFor string `json:"insertXforwardedFor,omitempty"` - LwsSeparator string `json:"lwsSeparator,omitempty"` - LwsWidth int `json:"lwsWidth,omitempty"` - Name string `json:"name,omitempty"` - OneconnectTransformations string `json:"oneconnectTransformations,omitempty"` - TmPartition string `json:"tmPartition,omitempty"` - ProxyType string `json:"proxyType,omitempty"` - RedirectRewrite string `json:"redirectRewrite,omitempty"` - RequestChunking string `json:"requestChunking,omitempty"` - ResponseChunking string `json:"responseChunking,omitempty"` - ResponseHeadersPermitted []interface{} `json:"responseHeadersPermitted,omitempty"` - ServerAgentName string `json:"serverAgentName,omitempty"` - ViaHostName string `json:"viaHostName,omitempty"` - ViaRequest string `json:"viaRequest,omitempty"` - ViaResponse string `json:"viaResponse,omitempty"` - XffAlternativeNames []interface{} `json:"xffAlternativeNames,omitempty"` - Hsts HTTPStrictTransportSecurity `json:"hsts,omitempty"` - Enforcement Enforcement `json:"enforcement,omitempty"` + AcceptXff string `json:"acceptXff,omitempty"` + AppService string `json:"appService,omitempty"` + BasicAuthRealm string `json:"basicAuthRealm,omitempty"` + DefaultsFrom string `json:"defaultsFrom,omitempty"` + Description string `json:"description,omitempty"` + EncryptCookieSecret string `json:"encryptCookieSecret,omitempty"` + EncryptCookies []string `json:"encryptCookies,omitempty"` + FallbackHost string `json:"fallbackHost,omitempty"` + FallbackStatusCodes []string `json:"fallbackStatusCodes,omitempty"` + HeaderErase string `json:"headerErase,omitempty"` + HeaderInsert string `json:"headerInsert,omitempty"` + InsertXforwardedFor string `json:"insertXforwardedFor,omitempty"` + LwsSeparator string `json:"lwsSeparator,omitempty"` + LwsWidth int `json:"lwsWidth,omitempty"` + Name string `json:"name,omitempty"` + OneconnectTransformations string `json:"oneconnectTransformations,omitempty"` + TmPartition string `json:"tmPartition,omitempty"` + ProxyType string `json:"proxyType,omitempty"` + RedirectRewrite string `json:"redirectRewrite,omitempty"` + RequestChunking string `json:"requestChunking,omitempty"` + ResponseChunking string `json:"responseChunking,omitempty"` + ResponseHeadersPermitted []interface{} `json:"responseHeadersPermitted,omitempty"` + ServerAgentName string `json:"serverAgentName,omitempty"` + ViaHostName string `json:"viaHostName,omitempty"` + ViaRequest string `json:"viaRequest,omitempty"` + ViaResponse string `json:"viaResponse,omitempty"` + XffAlternativeNames []interface{} `json:"xffAlternativeNames,omitempty"` + Hsts HTTPStrictTransportSecurity `json:"hsts,omitempty"` + Enforcement Enforcement `json:"enforcement,omitempty"` } type HTTPStrictTransportSecurity struct { @@ -1856,9 +1856,26 @@ type Enforcement struct { MaxRequests int OversizeClientHeaders string OversizeServerHeaders string - Pipeline string - TruncatedRedirects string - UnknownMethod string `json:"unknownMethod,omitempty"` + Pipeline string + TruncatedRedirects string + UnknownMethod string `json:"unknownMethod,omitempty"` +} + +type WebAccelerationProfileService struct { + Name string `json:"name,omitempty"` + DefaultsFrom string `json:"defaultsFrom,omitempty"` + CacheSize int `json:"cacheSize,omitempty"` + CacheMaxEntries int `json:"cacheMaxEntries,omitempty"` + CacheMaxAge int `json:"cacheMaxAge,omitempty"` + CacheObjectMinSize int `json:"cacheObjectMinSize,omitempty"` + CacheObjectMaxSize int `json:"cacheObjectMaxSize,omitempty"` + CacheUriExclude []string `json:"cacheUriExclude,omitempty"` + CacheUriInclude []string `json:"cacheUriInclude,omitempty"` + CacheUriIncludeOverride []string `json:"cacheUriIncludeOverride,omitempty"` + CacheUriPinned []string `json:"cacheUriPinned,omitempty"` + CacheClientCacheControlMode string `json:"cacheClientCacheControlMode,omitempty"` + CacheInsertAgeHeader string `json:"cacheInsertAgeHeader,omitempty"` + CacheAgingRate int `json:"cacheAgingRate,omitempty"` } type OneconnectProfiles struct { @@ -3827,6 +3844,20 @@ func (b *BigIP) GetHttpProfile(name string) (*HttpProfile, error) { return &httpProfile, nil } +func (b *BigIP) GetWebAccelerationProfile(name string) (*WebAccelerationProfileService, error) { + var webAccelerationProfileService WebAccelerationProfileService + err, ok := b.getForEntity(&webAccelerationProfileService, uriLtm, uriProfile, uriWebAcceleration, name) + if err != nil { + return nil, err + } + + if !ok { + return nil, nil + } + + return &webAccelerationProfileService, nil +} + // CreateHttpProfile creates a new http profile on the BIG-IP system. func (b *BigIP) CreateHttpProfile(name string, parent string) error { config := &HttpProfile{ @@ -3842,17 +3873,32 @@ func (b *BigIP) AddHttpProfile(config *HttpProfile) error { return b.post(config, uriLtm, uriProfile, uriHttp) } +// AddWebAcceleration creates a new web acceleration profile service on the BIG-IP system. +func (b *BigIP) AddWebAcceleration(config *WebAccelerationProfileService) error { + return b.post(config, uriLtm, uriProfile, uriWebAcceleration) +} + // DeleteHttpProfile removes a http profile. func (b *BigIP) DeleteHttpProfile(name string) error { return b.delete(uriLtm, uriProfile, uriHttp, name) } +// DeleteWebAccelerationProfile removes a web acceleration profile. +func (b *BigIP) DeleteWebAccelerationProfile(name string) error { + return b.delete(uriLtm, uriProfile, uriWebAcceleration, name) +} + // ModifyHttpProfile allows you to change any attribute of a http profile. // Fields that can be modified are referenced in the HttpProfile struct. func (b *BigIP) ModifyHttpProfile(name string, config *HttpProfile) error { return b.patch(config, uriLtm, uriProfile, uriHttp, name) } +// ModifyWebAccelerationProfile allows you to change any attribute of a Web Acceleration profile. +func (b *BigIP) ModifyWebAccelerationProfile(name string, config *WebAccelerationProfileService) error { + return b.patch(config, uriLtm, uriProfile, uriWebAcceleration, name) +} + // OneconnectProfiles returns a list of HTTP profiles func (b *BigIP) OneconnectProfiles() (*OneconnectProfiles, error) { var oneconnectProfiles OneconnectProfiles