diff --git a/incapsula/client_performance.go b/incapsula/client_performance.go index c63297d1..bcf0eddb 100644 --- a/incapsula/client_performance.go +++ b/incapsula/client_performance.go @@ -30,9 +30,9 @@ type PerformanceSettings struct { CacheShield bool `json:"cache_shield"` CacheResponseHeader struct { Mode string `json:"mode,omitempty"` - Headers []interface{} `json:"headers,omitempty"` + Headers []interface{} `json:"headers"` } `json:"cache_response_header,omitempty"` - TagResponseHeader string `json:"tag_response_header,omitempty"` + TagResponseHeader string `json:"tag_response_header"` CacheEmptyResponses bool `json:"cache_empty_responses"` Cache300X bool `json:"cache_300x"` CacheHTTP10Responses bool `json:"cache_http_10_responses"` @@ -53,14 +53,14 @@ type PerformanceSettings struct { } // GetPerformanceSettings gets the site performance settings -func (c *Client) GetPerformanceSettings(siteID string) (*PerformanceSettings, int, error) { +func (c *Client) GetPerformanceSettings(siteID string) (*PerformanceSettings, error) { log.Printf("[INFO] Getting Incapsula Performance Settings for Site ID %s\n", siteID) // Post form to Incapsula reqURL := fmt.Sprintf("%s/sites/%s/settings/cache", c.config.BaseURLRev2, siteID) resp, err := c.DoJsonRequestWithHeaders(http.MethodGet, reqURL, nil, ReadSitePerformance) if err != nil { - return nil, 0, fmt.Errorf("Error from Incapsula service when reading Incap Performance Settings for Site ID %s: %s", siteID, err) + return nil, fmt.Errorf("Error from Incapsula service when reading Incap Performance Settings for Site ID %s: %s", siteID, err) } // Read the body @@ -72,17 +72,17 @@ func (c *Client) GetPerformanceSettings(siteID string) (*PerformanceSettings, in // Check the response code if resp.StatusCode != 200 { - return nil, resp.StatusCode, fmt.Errorf("Error status code %d from Incapsula service when reading Incap Performance Settings for Site ID %s: %s", resp.StatusCode, siteID, string(responseBody)) + return nil, fmt.Errorf("Error status code %d from Incapsula service when reading Incap Performance Settings for Site ID %s: %s", resp.StatusCode, siteID, string(responseBody)) } // Parse the JSON var performanceSettings PerformanceSettings err = json.Unmarshal([]byte(responseBody), &performanceSettings) if err != nil { - return nil, resp.StatusCode, fmt.Errorf("Error parsing Incap Performance Settings JSON response for Site ID %s: %s\nresponse: %s", siteID, err, string(responseBody)) + return nil, fmt.Errorf("Error parsing Incap Performance Settings JSON response for Site ID %s: %s\nresponse: %s", siteID, err, string(responseBody)) } - return &performanceSettings, resp.StatusCode, nil + return &performanceSettings, nil } // UpdatePerformanceSettings updates the site performance settings diff --git a/incapsula/client_performance_test.go b/incapsula/client_performance_test.go index 67a55816..9de92625 100644 --- a/incapsula/client_performance_test.go +++ b/incapsula/client_performance_test.go @@ -17,7 +17,7 @@ func TestClientGetPerformanceSettingsBadConnection(t *testing.T) { config := &Config{APIID: "foo", APIKey: "bar", BaseURL: "badness.incapsula.com"} client := &Client{config: config, httpClient: &http.Client{Timeout: time.Millisecond * 1}} siteID := "123" - performanceSettings, _, err := client.GetPerformanceSettings(siteID) + performanceSettings, err := client.GetPerformanceSettings(siteID) if err == nil { t.Errorf("Should have received an error") } @@ -47,7 +47,7 @@ func TestClientGetPerformanceSettingsBadJSON(t *testing.T) { config := &Config{APIID: apiID, APIKey: apiKey, BaseURL: server.URL, BaseURLRev2: server.URL, BaseURLAPI: server.URL} client := &Client{config: config, httpClient: &http.Client{}} - performanceSettings, _, err := client.GetPerformanceSettings(siteID) + performanceSettings, err := client.GetPerformanceSettings(siteID) if err == nil { t.Errorf("Should have received an error") } @@ -78,7 +78,7 @@ func TestClientGetPerformanceSettingsInvalidSite(t *testing.T) { config := &Config{APIID: apiID, APIKey: apiKey, BaseURL: server.URL, BaseURLRev2: server.URL, BaseURLAPI: server.URL} client := &Client{config: config, httpClient: &http.Client{}} - performanceSettings, _, err := client.GetPerformanceSettings(siteID) + performanceSettings, err := client.GetPerformanceSettings(siteID) if err == nil { t.Errorf("Should have received an error") } @@ -108,7 +108,7 @@ func TestClientGetPerformanceSettingsValidSite(t *testing.T) { config := &Config{APIID: apiID, APIKey: apiKey, BaseURL: server.URL, BaseURLRev2: server.URL, BaseURLAPI: server.URL} client := &Client{config: config, httpClient: &http.Client{}} - performanceSettings, _, err := client.GetPerformanceSettings(siteID) + performanceSettings, err := client.GetPerformanceSettings(siteID) if err != nil { t.Errorf("Should not have received an error") } diff --git a/incapsula/provider.go b/incapsula/provider.go index c795a84f..ec5a569c 100644 --- a/incapsula/provider.go +++ b/incapsula/provider.go @@ -153,6 +153,7 @@ func Provider() *schema.Provider { "incapsula_abp_websites": resourceAbpWebsites(), "incapsula_delivery_rules_configuration": resourceDeliveryRulesConfiguration(), "incapsula_simplified_redirect_rules_configuration": resourceSimplifiedRedirectRulesConfiguration(), + "incapsula_application_performance": resourceApplicationPerformance(), }, } diff --git a/incapsula/resource_application_performance.go b/incapsula/resource_application_performance.go new file mode 100644 index 00000000..570ab241 --- /dev/null +++ b/incapsula/resource_application_performance.go @@ -0,0 +1,257 @@ +package incapsula + +import ( + "fmt" + "log" + "strconv" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceApplicationPerformance() *schema.Resource { + return &schema.Resource{ + Create: resourceApplicationPerformanceUpdate, + Read: resourceApplicationPerformanceRead, + Update: resourceApplicationPerformanceUpdate, + Delete: resourceApplicationPerformanceDelete, + Importer: &schema.ResourceImporter{ + State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + siteID, err := strconv.Atoi(d.Id()) + if err != nil { + return nil, fmt.Errorf("failed to convert Site Id from import command for Application Performance resource, actual value: %s, expected numeric id", d.Id()) + } + + d.Set("site_id", siteID) + log.Printf("[DEBUG] Import Application Performance for Site ID %d", siteID) + return []*schema.ResourceData{d}, nil + }, + }, + + Schema: map[string]*schema.Schema{ + // Required Arguments + "site_id": { + Description: "Numeric identifier of the site to operate on. ", + Type: schema.TypeInt, + Required: true, + ForceNew: true, + }, + "client_comply_no_cache": { + Description: "Comply with No-Cache and Max-Age directives in client requests. By default, these cache directives are ignored. Resources are dynamically profiled and re-configured to optimize performance.", + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "client_enable_client_side_caching": { + Description: "Cache content on client browsers or applications. When not enabled, content is cached only on the Imperva proxies.", + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "client_send_age_header": { + Description: "Send Cache-Control: max-age and Age headers.", + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "key_comply_vary": { + Description: "Comply with Vary. Cache resources in accordance with the Vary response header.", + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "key_unite_naked_full_cache": { + Description: "Use the Same Cache for Full and Naked Domains. For example, use the same cached resource for www.example.com/a and example.com/a.", + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "mode_https": { + Description: "The resources that are cached over HTTPS, the general level applies. Options are `disabled`, `dont_include_html`, `include_html`, and `include_all_resources`.", + Type: schema.TypeString, + Optional: true, + Default: "disabled", + ValidateFunc: validation.StringInSlice([]string{"disabled", "dont_include_html", "include_html", "include_all_resources"}, false), + }, + "mode_level": { + Description: "Caching level. Options are `disabled`, `standard`, `smart`, and `all_resources`.", + Type: schema.TypeString, + Optional: true, + Default: "smart", + ValidateFunc: validation.StringInSlice([]string{"disabled", "standard", "smart", "all_resources"}, false), + }, + "mode_time": { + Description: "The time, in seconds, that you set for this option determines how often the cache is refreshed. Relevant for the `include_html` and `include_all_resources` levels only.", + Type: schema.TypeInt, + Computed: true, + Optional: true, + }, + "response_cache_300x": { + Description: "When this option is checked Imperva will cache 301, 302, 303, 307, and 308 redirect response headers containing the target URI.", + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "response_cache_404_enabled": { + Description: "Whether or not to cache 404 responses.", + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "response_cache_404_time": { + Description: "The time in seconds to cache 404 responses.", + Type: schema.TypeInt, + Computed: true, + Optional: true, + ValidateFunc: validation.IntDivisibleBy(60), + }, + "response_cache_empty_responses": { + Description: "Cache responses that don’t have a message body.", + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "response_cache_http_10_responses": { + Description: "Cache HTTP 1.0 type responses that don’t include the Content-Length header or chunking.", + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "response_cache_response_header_mode": { + Description: "The working mode for caching response headers. Options are `all`, `custom` and `disabled`.", + Type: schema.TypeString, + Optional: true, + Default: "disabled", + ValidateFunc: validation.StringInSlice([]string{"disabled", "custom", "all"}, false), + }, + "response_cache_response_headers": { + Description: "An array of strings representing the response headers to be cached when working in `custom` mode. If empty, no response headers are cached.", + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Optional: true, + DefaultFunc: func() (interface{}, error) { + return []interface{}{}, nil + }, + DiffSuppressFunc: suppressEquivalentStringDiffs, + }, + "response_cache_shield": { + Description: "Adds an intermediate cache between other Imperva PoPs and your origin servers to protect your servers from redundant requests.", + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "response_stale_content_mode": { + Description: "The working mode for serving stale content. Options are `disabled`, `adaptive`, and `custom`.", + Type: schema.TypeString, + Optional: true, + Default: "disabled", + ValidateFunc: validation.StringInSlice([]string{"disabled", "adaptive", "custom"}, false), + }, + "response_stale_content_time": { + Description: "The time, in seconds, to serve stale content for when working in `custom` work mode.", + Type: schema.TypeInt, + Computed: true, + Optional: true, + }, + "response_tag_response_header": { + Description: "Tag the response according to the value of this header. Specify which origin response header contains the cache tags in your resources.", + Type: schema.TypeString, + Optional: true, + }, + "ttl_prefer_last_modified": { + Description: "Prefer 'Last Modified' over eTag. When this option is checked, Imperva prefers using Last Modified values (if available) over eTag values (recommended on multi-server setups).", + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "ttl_use_shortest_caching": { + Description: "Use shortest caching duration in case of conflicts. By default, the longest duration is used in case of conflict between caching rules or modes. When this option is checked, Imperva uses the shortest duration in case of conflict.", + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + }, + } +} + +func resourceApplicationPerformanceUpdate(d *schema.ResourceData, m interface{}) error { + client := m.(*Client) + siteID := d.Get("site_id").(int) + siteIdStr := strconv.Itoa(siteID) + + performanceSettings := PerformanceSettings{} + performanceSettings.ClientSide.ComplyNoCache = d.Get("client_comply_no_cache").(bool) + performanceSettings.ClientSide.EnableClientSideCaching = d.Get("client_enable_client_side_caching").(bool) + performanceSettings.ClientSide.SendAgeHeader = d.Get("client_send_age_header").(bool) + performanceSettings.Key.ComplyVary = d.Get("key_comply_vary").(bool) + performanceSettings.Key.UniteNakedFullCache = d.Get("key_unite_naked_full_cache").(bool) + performanceSettings.Mode.HTTPS = d.Get("mode_https").(string) + performanceSettings.Mode.Level = d.Get("mode_level").(string) + performanceSettings.Mode.Time = d.Get("mode_time").(int) + performanceSettings.Response.Cache300X = d.Get("response_cache_300x").(bool) + performanceSettings.Response.Cache404.Enabled = d.Get("response_cache_404_enabled").(bool) + performanceSettings.Response.Cache404.Time = d.Get("response_cache_404_time").(int) + performanceSettings.Response.CacheEmptyResponses = d.Get("response_cache_empty_responses").(bool) + performanceSettings.Response.CacheHTTP10Responses = d.Get("response_cache_http_10_responses").(bool) + performanceSettings.Response.CacheResponseHeader.Mode = d.Get("response_cache_response_header_mode").(string) + performanceSettings.Response.CacheResponseHeader.Headers = d.Get("response_cache_response_headers").([]interface{}) + performanceSettings.Response.CacheShield = d.Get("response_cache_shield").(bool) + performanceSettings.Response.StaleContent.Mode = d.Get("response_stale_content_mode").(string) + performanceSettings.Response.StaleContent.Time = d.Get("response_stale_content_time").(int) + performanceSettings.Response.TagResponseHeader = d.Get("response_tag_response_header").(string) + performanceSettings.TTL.PreferLastModified = d.Get("ttl_prefer_last_modified").(bool) + performanceSettings.TTL.UseShortestCaching = d.Get("ttl_use_shortest_caching").(bool) + + _, err := client.UpdatePerformanceSettings(siteIdStr, &performanceSettings) + if err != nil { + log.Printf("[ERROR] Could not update Incapsula performance settings for site_id: %s %s\n", d.Id(), err) + return err + } + + return resourceApplicationPerformanceRead(d, m) +} + +func resourceApplicationPerformanceRead(d *schema.ResourceData, m interface{}) error { + client := m.(*Client) + siteID := d.Get("site_id").(int) + siteIdStr := strconv.Itoa(siteID) + + performanceSettingsResponse, err := client.GetPerformanceSettings(siteIdStr) + if err != nil { + log.Printf("[ERROR] Could not read Incapsula site peformance settings for site id: %d, %s\n", siteID, err) + return err + } + + d.Set("client_comply_no_cache", performanceSettingsResponse.ClientSide.ComplyNoCache) + d.Set("client_enable_client_side_caching", performanceSettingsResponse.ClientSide.EnableClientSideCaching) + d.Set("client_send_age_header", performanceSettingsResponse.ClientSide.SendAgeHeader) + d.Set("key_comply_vary", performanceSettingsResponse.Key.ComplyVary) + d.Set("key_unite_naked_full_cache", performanceSettingsResponse.Key.UniteNakedFullCache) + d.Set("mode_https", performanceSettingsResponse.Mode.HTTPS) + d.Set("mode_level", performanceSettingsResponse.Mode.Level) + d.Set("mode_time", performanceSettingsResponse.Mode.Time) + d.Set("response_cache_300x", performanceSettingsResponse.Response.Cache300X) + d.Set("response_cache_404_enabled", performanceSettingsResponse.Response.Cache404.Enabled) + d.Set("response_cache_404_time", performanceSettingsResponse.Response.Cache404.Time) + d.Set("response_cache_empty_responses", performanceSettingsResponse.Response.CacheEmptyResponses) + d.Set("response_cache_http_10_responses", performanceSettingsResponse.Response.CacheHTTP10Responses) + d.Set("response_cache_response_header_mode", performanceSettingsResponse.Response.CacheResponseHeader.Mode) + d.Set("response_cache_response_headers", performanceSettingsResponse.Response.CacheResponseHeader.Headers) + d.Set("response_cache_shield", performanceSettingsResponse.Response.CacheShield) + d.Set("response_stale_content_mode", performanceSettingsResponse.Response.StaleContent.Mode) + d.Set("response_stale_content_time", performanceSettingsResponse.Response.StaleContent.Time) + d.Set("response_tag_response_header", performanceSettingsResponse.Response.TagResponseHeader) + d.Set("ttl_prefer_last_modified", performanceSettingsResponse.TTL.PreferLastModified) + d.Set("ttl_use_shortest_caching", performanceSettingsResponse.TTL.UseShortestCaching) + + d.SetId(siteIdStr) + + return nil +} + +func resourceApplicationPerformanceDelete(d *schema.ResourceData, m interface{}) error { + d.SetId("") + return nil +} diff --git a/incapsula/resource_application_performance_test.go b/incapsula/resource_application_performance_test.go new file mode 100644 index 00000000..10441dc6 --- /dev/null +++ b/incapsula/resource_application_performance_test.go @@ -0,0 +1,184 @@ +package incapsula + +import ( + "fmt" + "log" + "strconv" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +const applicationPerformanceResourceName = "incapsula_application_performance" +const applicationPerformanceResource = applicationPerformanceResourceName + "." + applicationPerformanceName +const applicationPerformanceName = "testacc-terraform-application_performance" + +func TestAccIncapsulaApplicationPerformance_basic(t *testing.T) { + var domainName = GenerateTestDomain(t) + log.Printf("======================== BEGIN TEST ========================") + log.Printf("[DEBUG] Running test resource_application_performance_test.TestAccIncapsulaApplicationPerformance_basic") + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAllCachingEnabled(domainName), + Check: resource.ComposeTestCheckFunc( + testCheckApplicationPerformanceExists(applicationPerformanceResource), + resource.TestCheckResourceAttr(applicationPerformanceResource, "client_comply_no_cache", "true"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "client_enable_client_side_caching", "true"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "client_send_age_header", "true"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "key_comply_vary", "true"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "key_unite_naked_full_cache", "true"), + + resource.TestCheckResourceAttr(applicationPerformanceResource, "mode_level", "all_resources"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "mode_https", "disabled"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "mode_time", "120"), + + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_300x", "true"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_404_enabled", "true"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_404_time", "120"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_empty_responses", "true"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_http_10_responses", "true"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_response_header_mode", "custom"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_response_headers.#", "1"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_response_headers.0", "cache2"), + + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_stale_content_mode", "custom"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_stale_content_time", "120"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_tag_response_header", "myHeader3"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "ttl_prefer_last_modified", "true"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "ttl_use_shortest_caching", "true"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_shield", "false"), + ), + }, + { + Config: testAllCachingDisabled(domainName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(applicationPerformanceResource, "client_comply_no_cache", "false"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "client_enable_client_side_caching", "false"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "client_send_age_header", "false"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "key_comply_vary", "false"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "key_unite_naked_full_cache", "false"), + + resource.TestCheckResourceAttr(applicationPerformanceResource, "mode_level", "disabled"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "mode_https", "disabled"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "mode_time", "0"), + + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_300x", "false"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_404_enabled", "false"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_404_time", "0"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_empty_responses", "false"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_http_10_responses", "false"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_response_header_mode", "disabled"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_response_headers.#", "0"), + + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_stale_content_mode", "disabled"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_stale_content_time", "0"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_tag_response_header", ""), + resource.TestCheckResourceAttr(applicationPerformanceResource, "ttl_prefer_last_modified", "false"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "ttl_use_shortest_caching", "false"), + resource.TestCheckResourceAttr(applicationPerformanceResource, "response_cache_shield", "false"), + ), + }, + { + ResourceName: applicationPerformanceResource, + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: testAccStateApplicationPerformanceID, + }, + }, + }) +} + +func testCheckApplicationPerformanceExists(name string) resource.TestCheckFunc { + return func(state *terraform.State) error { + _, ok := state.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Incapsula Application Performance resource not found: %s", name) + } + + client := testAccProvider.Meta().(*Client) + _, err2 := client.GetPerformanceSettings(siteId) + if err2 != nil { + fmt.Errorf("Incapsula Application Performance doesn't exist") + } + + return nil + } +} + +func testAccStateApplicationPerformanceID(s *terraform.State) (string, error) { + for _, rs := range s.RootModule().Resources { + if rs.Type != applicationPerformanceResourceName { + continue + } + + siteID, err := strconv.Atoi(rs.Primary.Attributes["site_id"]) + + if err != nil { + return "", fmt.Errorf("Error parsing ID %v to int in Application Performance resource test", rs.Primary.Attributes["site_id"]) + } + return fmt.Sprintf("%d", siteID), nil + } + return "", fmt.Errorf("Error finding site_id argument in Application Performance resource test") +} + +func testAllCachingEnabled(domainName string) string { + return testCheckIncapsulaSiteV3ConfigBasic(domainName, "CLOUD_WAF") + fmt.Sprintf(` +resource "%s" "%s" { + site_id = incapsula_site_v3.test-terraform-site-v3.id + depends_on = ["incapsula_site_v3.test-terraform-site-v3"] + client_comply_no_cache = true + client_enable_client_side_caching = true + client_send_age_header = true + key_comply_vary = true + key_unite_naked_full_cache = true + mode_level = "all_resources" + mode_https = "disabled" + mode_time = 120 + response_cache_300x = true + response_cache_404_enabled = true + response_cache_404_time = 120 + response_cache_empty_responses = true + response_cache_http_10_responses = true + response_cache_response_header_mode = "custom" + response_cache_response_headers = ["cache2"] + response_stale_content_mode = "custom" + response_tag_response_header = "myHeader3" + response_stale_content_time = 120 + ttl_prefer_last_modified = true + ttl_use_shortest_caching = true +}`, + applicationPerformanceResourceName, applicationPerformanceName, + ) +} + +func testAllCachingDisabled(domainName string) string { + return testCheckIncapsulaSiteV3ConfigBasic(domainName, "CLOUD_WAF") + fmt.Sprintf(` +resource "%s" "%s" { + site_id = incapsula_site_v3.test-terraform-site-v3.id + depends_on = ["incapsula_site_v3.test-terraform-site-v3"] + client_comply_no_cache = false + client_enable_client_side_caching = false + client_send_age_header = false + key_comply_vary = false + key_unite_naked_full_cache = false + mode_level = "disabled" + mode_https = "disabled" + mode_time = 0 + response_cache_300x = false + response_cache_404_enabled = false + response_cache_404_time = 0 + response_cache_empty_responses = false + response_cache_http_10_responses = false + response_cache_response_header_mode = "disabled" + response_stale_content_mode = "disabled" + response_stale_content_time = 0 + ttl_prefer_last_modified = false + ttl_use_shortest_caching = false +}`, + applicationPerformanceResourceName, applicationPerformanceName, + ) +} diff --git a/incapsula/resource_site.go b/incapsula/resource_site.go index 47636c77..ba1488e2 100644 --- a/incapsula/resource_site.go +++ b/incapsula/resource_site.go @@ -514,7 +514,7 @@ func resourceSiteRead(d *schema.ResourceData, m interface{}) error { d.Set("hash_salt", maskingResponse.HashSalt) // Get the performance settings for the site - performanceSettingsResponse, _, err := client.GetPerformanceSettings(d.Id()) + performanceSettingsResponse, err := client.GetPerformanceSettings(d.Id()) if err != nil { log.Printf("[ERROR] Could not read Incapsula site peformance settings for domain: %s and site id: %d, %s\n", domain, siteID, err) return err diff --git a/website/docs/r/application_delivery.html.markdown b/website/docs/r/application_delivery.html.markdown index f2c02f98..de8c257a 100644 --- a/website/docs/r/application_delivery.html.markdown +++ b/website/docs/r/application_delivery.html.markdown @@ -9,7 +9,6 @@ description: |- # incapsula_application_delivery Configure delivery options to help you optimize your content delivery and improve performance by providing faster loading of your web pages. -Note that the destroy command returns the configuration to the default values. ## Example Usage diff --git a/website/docs/r/application_performance.html.markdown b/website/docs/r/application_performance.html.markdown new file mode 100644 index 00000000..042394fb --- /dev/null +++ b/website/docs/r/application_performance.html.markdown @@ -0,0 +1,84 @@ +--- +subcategory: "Provider Reference" +layout: "incapsula" +page_title: "incapsula_application_performance" +description: |- + Provides a Incapsula Application Performance resource. +--- + +# incapsula_application_performance + +Configure content caching for your website. + +## Example Usage + +### Basic Usage - Application Performance + +```hcl +resource "incapsula_application_performance" "example_application_performance" { + site_id = incapsula_site.testacc-terraform-site.id + client_comply_no_cache = true + client_enable_client_side_caching = true + client_send_age_header = true + key_comply_vary = true + key_unite_naked_full_cache = true + mode_https = "include_all_resources" + mode_level = "standard" + mode_time = 1000 + response_cache_300x = true + response_cache_404_enabled = true + response_cache_404_time = 60 + response_cache_empty_responses = true + response_cache_http_10_responses = true + response_cache_response_header_mode = "custom" + response_cache_response_headers = ["Access-Control-Allow-Origin", "Foo-Bar-Header"] + response_cache_shield = true + response_stale_content_mode = "custom" + response_stale_content_time = 1000 + response_tag_response_header = "Example-Tag-Value-Header" + ttl_prefer_last_modified = true + ttl_use_shortest_caching = true +} +``` + +## Argument Reference + +The following arguments are supported: + +* `client_comply_no_cache` - (Optional) Comply with No-Cache and Max-Age directives in client requests. By default, these cache directives are ignored. Resources are dynamically profiled and re-configured to optimize performance. **Default:** false +* `client_enable_client_side_caching` - (Optional) Cache content on client browsers or applications. When not enabled, content is cached only on the Imperva proxies. **Default:** false +* `client_send_age_header` - (Optional) Send Cache-Control: max-age and Age headers. **Default:** false +* `key_comply_vary` - (Optional) Comply with Vary. Cache resources in accordance with the Vary response header. **Default:** false +* `key_unite_naked_full_cache` - (Optional) Use the Same Cache for Full and Naked Domains. For example, use the same cached resource for www.example.com/a and example.com/a. **Default:** false +* `mode_https` - (Optional) The resources that are cached over HTTPS, the general level applies. Options are `disabled`, `dont_include_html`, `include_html`, and `include_all_resources`. **Default:** `disabled` +* `mode_level` - (Optional) Caching level. Options are `disabled`, `custom_cache_rules_only`, `standard`, `smart`, and `all_resources`. **Default:** smart +* `mode_time` - (Optional) The time, in seconds, that you set for this option determines how often the cache is refreshed. Relevant for the `include_html` and `include_all_resources` levels only. +* `response_cache_300x` - (Optional) When this option is checked Imperva will cache 301, 302, 303, 307, and 308 redirect response headers containing the target URI. **Default:** false +* `response_cache_404_enabled` - (Optional) Whether or not to cache 404 responses. **Default:** false +* `response_cache_404_time` - (Optional) The time in seconds to cache 404 responses. Value should be divisible by + 60. +* `response_cache_empty_responses` - (Optional) Cache responses that don’t have a message body. **Default:** false +* `response_cache_http_10_responses` - (Optional) Cache HTTP 1.0 type responses that don’t include the Content-Length header or chunking. **Default:** false +* `response_cache_response_header_mode` - (Optional) The working mode for caching response headers. Options are `all`, `custom` and `disabled`. **Default:** `disabled` +* `response_cache_response_headers` - (Optional) An array of strings representing the response headers to be cached when working in `custom` mode. If empty, no response headers are cached. +For example: `["Access-Control-Allow-Origin","Access-Control-Allow-Methods"]`. +* `response_cache_shield` - (Optional) Adds an intermediate cache between other Imperva PoPs and your origin servers to protect your servers from redundant requests. **Default:** false +* `response_stale_content_mode` - (Optional) The working mode for serving stale content. Options are `disabled`, `adaptive`, and `custom`. **Default:** `disabled` +* `response_stale_content_time` - (Optional) The time, in seconds, to serve stale content for when working in `custom` work mode. +* `response_tag_response_header` - (Optional) Tag the response according to the value of this header. Specify which origin response header contains the cache tags in your resources. +* `ttl_prefer_last_modified` - (Optional) Prefer 'Last Modified' over eTag. When this option is checked, Imperva prefers using Last Modified values (if available) over eTag values (recommended on multi-server setups). **Default:** false +* `ttl_use_shortest_caching` - (Optional) Use shortest caching duration in case of conflicts. By default, the longest duration is used in case of conflict between caching rules or modes. When this option is checked, Imperva uses the shortest duration in case of conflict. **Default:** false + +## Attributes Reference + +The following attributes are exported: + +* `id` - Unique identifier in the API for the application performance configuration. The id is identical to Site id. + +## Import + +Application performance configuration can be imported using the `id`, e.g.: + +``` +$ terraform import incapsula_application_performance.example_application_performance 1234 +``` diff --git a/website/docs/r/site.html.markdown b/website/docs/r/site.html.markdown index 501f7359..0076a53b 100644 --- a/website/docs/r/site.html.markdown +++ b/website/docs/r/site.html.markdown @@ -93,7 +93,7 @@ The following arguments are supported: 60. * `perf_response_cache_empty_responses` - (Optional) Cache responses that don’t have a message body. * `perf_response_cache_http_10_responses` - (Optional) Cache HTTP 1.0 type responses that don’t include the Content-Length header or chunking. -* `perf_response_cache_response_header_mode` - (Optional) The working mode for caching response headers. Options are `all` and `custom`. +* `perf_response_cache_response_header_mode` - (Optional) The working mode for caching response headers. Options are `all`, `custom` and `disabled`. * `perf_response_cache_response_headers` - (Optional) An array of strings representing the response headers to be cached when working in `custom` mode. If empty, no response headers are cached. For example: `["Access-Control-Allow-Origin","Access-Control-Allow-Methods"]`. * `perf_response_cache_shield` - (Optional) Adds an intermediate cache between other Imperva PoPs and your origin servers to protect your servers from redundant requests.