|
| 1 | +package incapsula |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "log" |
| 6 | + "strconv" |
| 7 | + |
| 8 | + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" |
| 9 | + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" |
| 10 | +) |
| 11 | + |
| 12 | +func resourceSiteCacheConfiguration() *schema.Resource { |
| 13 | + return &schema.Resource{ |
| 14 | + Create: resourceApplicationPerformanceUpdate, |
| 15 | + Read: resourceApplicationPerformanceRead, |
| 16 | + Update: resourceApplicationPerformanceUpdate, |
| 17 | + Delete: resourceApplicationPerformanceDelete, |
| 18 | + Importer: &schema.ResourceImporter{ |
| 19 | + State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { |
| 20 | + siteID, err := strconv.Atoi(d.Id()) |
| 21 | + if err != nil { |
| 22 | + return nil, fmt.Errorf("failed to convert Site Id from import command for Site Cache Configuration resource, actual value: %s, expected numeric id", d.Id()) |
| 23 | + } |
| 24 | + |
| 25 | + d.Set("site_id", siteID) |
| 26 | + log.Printf("[DEBUG] Import Site Cache Configuration for Site ID %d", siteID) |
| 27 | + return []*schema.ResourceData{d}, nil |
| 28 | + }, |
| 29 | + }, |
| 30 | + |
| 31 | + Schema: map[string]*schema.Schema{ |
| 32 | + // Required Arguments |
| 33 | + "site_id": { |
| 34 | + Description: "Numeric identifier of the site to operate on. ", |
| 35 | + Type: schema.TypeInt, |
| 36 | + Required: true, |
| 37 | + ForceNew: true, |
| 38 | + }, |
| 39 | + "client_comply_no_cache": { |
| 40 | + 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.", |
| 41 | + Type: schema.TypeBool, |
| 42 | + Optional: true, |
| 43 | + Default: false, |
| 44 | + }, |
| 45 | + "client_enable_client_side_caching": { |
| 46 | + Description: "Cache content on client browsers or applications. When not enabled, content is cached only on the Imperva proxies.", |
| 47 | + Type: schema.TypeBool, |
| 48 | + Optional: true, |
| 49 | + Default: false, |
| 50 | + }, |
| 51 | + "client_send_age_header": { |
| 52 | + Description: "Send Cache-Control: max-age and Age headers.", |
| 53 | + Type: schema.TypeBool, |
| 54 | + Optional: true, |
| 55 | + Default: false, |
| 56 | + }, |
| 57 | + "key_comply_vary": { |
| 58 | + Description: "Comply with Vary. Cache resources in accordance with the Vary response header.", |
| 59 | + Type: schema.TypeBool, |
| 60 | + Optional: true, |
| 61 | + Default: false, |
| 62 | + }, |
| 63 | + "key_unite_naked_full_cache": { |
| 64 | + 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.", |
| 65 | + Type: schema.TypeBool, |
| 66 | + Optional: true, |
| 67 | + Default: false, |
| 68 | + }, |
| 69 | + "mode_https": { |
| 70 | + Description: "The resources that are cached over HTTPS, the general level applies. Options are `disabled`, `dont_include_html`, `include_html`, and `include_all_resources`.", |
| 71 | + Type: schema.TypeString, |
| 72 | + Optional: true, |
| 73 | + Default: "disabled", |
| 74 | + ValidateFunc: validation.StringInSlice([]string{"disabled", "dont_include_html", "include_html", "include_all_resources"}, false), |
| 75 | + }, |
| 76 | + "mode_level": { |
| 77 | + Description: "Caching level. Options are `disabled`, `custom_cache_rules_only`, `standard`, `smart`, and `all_resources`.", |
| 78 | + Type: schema.TypeString, |
| 79 | + Optional: true, |
| 80 | + Default: "smart", |
| 81 | + ValidateFunc: validation.StringInSlice([]string{"disabled", "custom_cache_rules_only", "standard", "smart", "all_resources"}, false), |
| 82 | + }, |
| 83 | + "mode_time": { |
| 84 | + 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.", |
| 85 | + Type: schema.TypeInt, |
| 86 | + Optional: true, |
| 87 | + Default: 0, |
| 88 | + }, |
| 89 | + "response_cache_300x": { |
| 90 | + Description: "When this option is checked Imperva will cache 301, 302, 303, 307, and 308 redirect response headers containing the target URI.", |
| 91 | + Type: schema.TypeBool, |
| 92 | + Optional: true, |
| 93 | + Default: false, |
| 94 | + }, |
| 95 | + "response_cache_404_enabled": { |
| 96 | + Description: "Whether or not to cache 404 responses.", |
| 97 | + Type: schema.TypeBool, |
| 98 | + Optional: true, |
| 99 | + Default: false, |
| 100 | + }, |
| 101 | + "response_cache_404_time": { |
| 102 | + Description: "The time in seconds to cache 404 responses.", |
| 103 | + Type: schema.TypeInt, |
| 104 | + Optional: true, |
| 105 | + Default: 0, |
| 106 | + ValidateFunc: validation.IntDivisibleBy(60), |
| 107 | + }, |
| 108 | + "response_cache_empty_responses": { |
| 109 | + Description: "Cache responses that don’t have a message body.", |
| 110 | + Type: schema.TypeBool, |
| 111 | + Optional: true, |
| 112 | + Default: false, |
| 113 | + }, |
| 114 | + "response_cache_http_10_responses": { |
| 115 | + Description: "Cache HTTP 1.0 type responses that don’t include the Content-Length header or chunking.", |
| 116 | + Type: schema.TypeBool, |
| 117 | + Optional: true, |
| 118 | + Default: false, |
| 119 | + }, |
| 120 | + "response_cache_response_header_mode": { |
| 121 | + Description: "The working mode for caching response headers. Options are `all`, `custom` and `disabled`.", |
| 122 | + Type: schema.TypeString, |
| 123 | + Optional: true, |
| 124 | + Default: "disabled", |
| 125 | + ValidateFunc: validation.StringInSlice([]string{"disabled", "custom", "all"}, false), |
| 126 | + }, |
| 127 | + "response_cache_response_headers": { |
| 128 | + Description: "An array of strings representing the response headers to be cached when working in `custom` mode. If empty, no response headers are cached.", |
| 129 | + Type: schema.TypeSet, |
| 130 | + Elem: &schema.Schema{ |
| 131 | + Type: schema.TypeString, |
| 132 | + }, |
| 133 | + Optional: true, |
| 134 | + }, |
| 135 | + "response_cache_shield": { |
| 136 | + Description: "Adds an intermediate cache between other Imperva PoPs and your origin servers to protect your servers from redundant requests.", |
| 137 | + Type: schema.TypeBool, |
| 138 | + Optional: true, |
| 139 | + Default: false, |
| 140 | + }, |
| 141 | + "response_stale_content_mode": { |
| 142 | + Description: "The working mode for serving stale content. Options are `disabled`, `adaptive`, and `custom`.", |
| 143 | + Type: schema.TypeString, |
| 144 | + Optional: true, |
| 145 | + Default: "disabled", |
| 146 | + ValidateFunc: validation.StringInSlice([]string{"disabled", "adaptive", "custom"}, false), |
| 147 | + }, |
| 148 | + "response_stale_content_time": { |
| 149 | + Description: "The time, in seconds, to serve stale content for when working in `custom` work mode.", |
| 150 | + Type: schema.TypeInt, |
| 151 | + Optional: true, |
| 152 | + Default: 0, |
| 153 | + }, |
| 154 | + "response_tag_response_header": { |
| 155 | + Description: "Tag the response according to the value of this header. Specify which origin response header contains the cache tags in your resources.", |
| 156 | + Type: schema.TypeString, |
| 157 | + Optional: true, |
| 158 | + }, |
| 159 | + "ttl_prefer_last_modified": { |
| 160 | + 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).", |
| 161 | + Type: schema.TypeBool, |
| 162 | + Optional: true, |
| 163 | + Default: false, |
| 164 | + }, |
| 165 | + "ttl_use_shortest_caching": { |
| 166 | + 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.", |
| 167 | + Type: schema.TypeBool, |
| 168 | + Optional: true, |
| 169 | + Default: false, |
| 170 | + }, |
| 171 | + }, |
| 172 | + } |
| 173 | +} |
| 174 | + |
| 175 | +func resourceApplicationPerformanceUpdate(d *schema.ResourceData, m interface{}) error { |
| 176 | + client := m.(*Client) |
| 177 | + siteID := d.Get("site_id").(int) |
| 178 | + siteIdStr := strconv.Itoa(siteID) |
| 179 | + |
| 180 | + performanceSettings := PerformanceSettings{} |
| 181 | + performanceSettings.ClientSide.ComplyNoCache = d.Get("client_comply_no_cache").(bool) |
| 182 | + performanceSettings.ClientSide.EnableClientSideCaching = d.Get("client_enable_client_side_caching").(bool) |
| 183 | + performanceSettings.ClientSide.SendAgeHeader = d.Get("client_send_age_header").(bool) |
| 184 | + performanceSettings.Key.ComplyVary = d.Get("key_comply_vary").(bool) |
| 185 | + performanceSettings.Key.UniteNakedFullCache = d.Get("key_unite_naked_full_cache").(bool) |
| 186 | + performanceSettings.Mode.HTTPS = d.Get("mode_https").(string) |
| 187 | + performanceSettings.Mode.Level = d.Get("mode_level").(string) |
| 188 | + performanceSettings.Mode.Time = d.Get("mode_time").(int) |
| 189 | + performanceSettings.Response.Cache300X = d.Get("response_cache_300x").(bool) |
| 190 | + performanceSettings.Response.Cache404.Enabled = d.Get("response_cache_404_enabled").(bool) |
| 191 | + performanceSettings.Response.Cache404.Time = d.Get("response_cache_404_time").(int) |
| 192 | + performanceSettings.Response.CacheEmptyResponses = d.Get("response_cache_empty_responses").(bool) |
| 193 | + performanceSettings.Response.CacheHTTP10Responses = d.Get("response_cache_http_10_responses").(bool) |
| 194 | + performanceSettings.Response.CacheResponseHeader.Mode = d.Get("response_cache_response_header_mode").(string) |
| 195 | + performanceSettings.Response.CacheResponseHeader.Headers = d.Get("response_cache_response_headers").(*schema.Set).List() |
| 196 | + performanceSettings.Response.CacheShield = d.Get("response_cache_shield").(bool) |
| 197 | + performanceSettings.Response.StaleContent.Mode = d.Get("response_stale_content_mode").(string) |
| 198 | + performanceSettings.Response.StaleContent.Time = d.Get("response_stale_content_time").(int) |
| 199 | + performanceSettings.Response.TagResponseHeader = d.Get("response_tag_response_header").(string) |
| 200 | + performanceSettings.TTL.PreferLastModified = d.Get("ttl_prefer_last_modified").(bool) |
| 201 | + performanceSettings.TTL.UseShortestCaching = d.Get("ttl_use_shortest_caching").(bool) |
| 202 | + |
| 203 | + _, err := client.UpdatePerformanceSettings(siteIdStr, &performanceSettings) |
| 204 | + if err != nil { |
| 205 | + log.Printf("[ERROR] Could not update Incapsula performance settings for site_id: %s %s\n", d.Id(), err) |
| 206 | + return err |
| 207 | + } |
| 208 | + |
| 209 | + return resourceApplicationPerformanceRead(d, m) |
| 210 | +} |
| 211 | + |
| 212 | +func resourceApplicationPerformanceRead(d *schema.ResourceData, m interface{}) error { |
| 213 | + client := m.(*Client) |
| 214 | + siteID := d.Get("site_id").(int) |
| 215 | + siteIdStr := strconv.Itoa(siteID) |
| 216 | + |
| 217 | + performanceSettingsResponse, err := client.GetPerformanceSettings(siteIdStr) |
| 218 | + if err != nil { |
| 219 | + log.Printf("[ERROR] Could not read Incapsula site peformance settings for site id: %d, %s\n", siteID, err) |
| 220 | + return err |
| 221 | + } |
| 222 | + |
| 223 | + d.Set("client_comply_no_cache", performanceSettingsResponse.ClientSide.ComplyNoCache) |
| 224 | + d.Set("client_enable_client_side_caching", performanceSettingsResponse.ClientSide.EnableClientSideCaching) |
| 225 | + d.Set("client_send_age_header", performanceSettingsResponse.ClientSide.SendAgeHeader) |
| 226 | + d.Set("key_comply_vary", performanceSettingsResponse.Key.ComplyVary) |
| 227 | + d.Set("key_unite_naked_full_cache", performanceSettingsResponse.Key.UniteNakedFullCache) |
| 228 | + d.Set("mode_https", performanceSettingsResponse.Mode.HTTPS) |
| 229 | + d.Set("mode_level", performanceSettingsResponse.Mode.Level) |
| 230 | + d.Set("mode_time", performanceSettingsResponse.Mode.Time) |
| 231 | + d.Set("response_cache_300x", performanceSettingsResponse.Response.Cache300X) |
| 232 | + d.Set("response_cache_404_enabled", performanceSettingsResponse.Response.Cache404.Enabled) |
| 233 | + d.Set("response_cache_404_time", performanceSettingsResponse.Response.Cache404.Time) |
| 234 | + d.Set("response_cache_empty_responses", performanceSettingsResponse.Response.CacheEmptyResponses) |
| 235 | + d.Set("response_cache_http_10_responses", performanceSettingsResponse.Response.CacheHTTP10Responses) |
| 236 | + d.Set("response_cache_response_header_mode", performanceSettingsResponse.Response.CacheResponseHeader.Mode) |
| 237 | + d.Set("response_cache_response_headers", performanceSettingsResponse.Response.CacheResponseHeader.Headers) |
| 238 | + d.Set("response_cache_shield", performanceSettingsResponse.Response.CacheShield) |
| 239 | + d.Set("response_stale_content_mode", performanceSettingsResponse.Response.StaleContent.Mode) |
| 240 | + d.Set("response_stale_content_time", performanceSettingsResponse.Response.StaleContent.Time) |
| 241 | + d.Set("response_tag_response_header", performanceSettingsResponse.Response.TagResponseHeader) |
| 242 | + d.Set("ttl_prefer_last_modified", performanceSettingsResponse.TTL.PreferLastModified) |
| 243 | + d.Set("ttl_use_shortest_caching", performanceSettingsResponse.TTL.UseShortestCaching) |
| 244 | + |
| 245 | + d.SetId(siteIdStr) |
| 246 | + |
| 247 | + return nil |
| 248 | +} |
| 249 | + |
| 250 | +func resourceApplicationPerformanceDelete(d *schema.ResourceData, m interface{}) error { |
| 251 | + d.SetId("") |
| 252 | + return nil |
| 253 | +} |
0 commit comments