diff --git a/bigip/provider.go b/bigip/provider.go index 51c622122..17f4dba3d 100644 --- a/bigip/provider.go +++ b/bigip/provider.go @@ -191,6 +191,8 @@ func Provider() *schema.Provider { "bigip_partition": resourceBigipPartition(), "bigip_ltm_request_log_profile": resourceBigipLtmProfileRequestLog(), "bigip_ltm_profile_bot_defense": resourceBigipLtmProfileBotDefense(), + "bigip_ltm_profile_rewrite": resourceBigipLtmRewriteProfile(), + "bigip_ltm_profile_rewrite_uri_rules": resourceBigipLtmRewriteProfileUriRules(), }, } p.ConfigureContextFunc = func(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { diff --git a/bigip/resource_bigip_ltm_profile_rewrite.go b/bigip/resource_bigip_ltm_profile_rewrite.go new file mode 100644 index 000000000..e1eb90af2 --- /dev/null +++ b/bigip/resource_bigip_ltm_profile_rewrite.go @@ -0,0 +1,369 @@ +/* +Original work from https://github.com/DealerDotCom/terraform-provider-bigip +Modifications Copyright 2024 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" + "fmt" + "log" + + bigip "github.com/f5devcentral/go-bigip" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceBigipLtmRewriteProfile() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceBigipLtmRewriteProfileCreate, + ReadContext: resourceBigipLtmProfileRewriteRead, + UpdateContext: resourceBigipLtmProfileRewriteUpdate, + DeleteContext: resourceBigipLtmProfileRewriteDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the rewrite profile.", + ValidateFunc: validateF5NameWithDirectory, + }, + "defaults_from": { + Type: schema.TypeString, + Optional: true, + Description: "Inherit defaults from parent profile.", + }, + "bypass_list": { + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + Description: "Specifies a list of URIs to bypass inside a web page when the page is accessed using Portal Access.", + }, + "cache_type": { + Type: schema.TypeString, + Optional: true, + Default: "cache-img-css-js", + Description: "Specifies the type of client caching.", + ValidateFunc: validation.StringInSlice([]string{"cache-css-js", "cache-all", "no-cache", "cache-img-css-js"}, false), + }, + "ca_file": { + Type: schema.TypeString, + Optional: true, + Description: "Specifies a CA against which to verify signed Java applets signatures.", + ValidateFunc: validateF5Name, + }, + "crl_file": { + Type: schema.TypeString, + Optional: true, + Default: "none", + Description: "Specifies a CRL against which to verify signed Java applets signature certificates.", + }, + "signing_cert": { + Type: schema.TypeString, + Optional: true, + Description: "Specifies a certificate to use for re-signing of signed Java applets after patching.", + ValidateFunc: validateF5Name, + }, + "signing_key": { + Type: schema.TypeString, + Optional: true, + Description: "Specifies a private key for re-signing of signed Java applets after patching.", + ValidateFunc: validateF5Name, + }, + "split_tunneling": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Specifies a private key for re-signing of signed Java applets after patching.", + ValidateFunc: validation.StringInSlice([]string{"true", "false"}, false), + }, + "signing_key_password": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + Description: "Specifies a pass phrase to use for encrypting the private signing key.", + ValidateFunc: validateF5Name, + }, + "rewrite_list": { + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + Description: "Specifies a list of URIs to rewrite inside a web page when the page is accessed using Portal Access.", + }, + "rewrite_mode": { + Type: schema.TypeString, + Required: true, + Description: "Specifies the type of rewrite operations.", + ValidateFunc: validation.StringInSlice([]string{"portal", "uri-translation"}, false), + }, + "request": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "insert_xfwd_for": { + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{"enabled", "disabled"}, false), + Optional: true, + Description: "Enable to add the X-Forwarded For (XFF) header, to specify the originating IP address of the client.", + }, + "insert_xfwd_host": { + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{"enabled", "disabled"}, false), + Optional: true, + Description: "Enable to add the X-Forwarded Host header, to specify the originating host of the client.", + }, + "insert_xfwd_protocol": { + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{"enabled", "disabled"}, false), + Optional: true, + Description: "Enable to add the X-Forwarded Proto header, to specify the originating protocol of the client.", + }, + "rewrite_headers": { + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{"enabled", "disabled"}, false), + Optional: true, + Description: "Enable to rewrite headers in Request settings.", + }, + }, + }, + }, + "response": { + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "rewrite_content": { + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{"enabled", "disabled"}, false), + Optional: true, + Description: "Enable to rewrite links in content in the response.", + }, + "rewrite_headers": { + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{"enabled", "disabled"}, false), + Optional: true, + Description: "Enable to rewrite headers in the response.", + }, + }, + }, + }, + "cookie_rules": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "rule_name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the cookie rewrite rule.", + }, + "client_domain": { + Type: schema.TypeString, + Required: true, + }, + "client_path": { + Type: schema.TypeString, + Required: true, + }, + "server_domain": { + Type: schema.TypeString, + Required: true, + }, + "server_path": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + }, + } +} + +func resourceBigipLtmRewriteProfileCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + + name := d.Get("name").(string) + // partition := strings.Split(name, "/")[1] + + pss := &bigip.RewriteProfile{ + Name: name, + // Partition: partition, + } + log.Printf("[INFO] Creating LTM rewrite profile config") + config := getRewriteProfileConfig(d, pss) + log.Printf("Config value:%+v", config) + + log.Printf("[INFO] Creating LTM rewrite profile") + err := client.AddRewriteProfile(config) + if err != nil { + log.Printf("[ERROR] Unable to Create Rewrite Profile %s %v :", name, err) + return diag.FromErr(err) + } + d.SetId(name) + + return resourceBigipLtmProfileRewriteRead(ctx, d, meta) +} +func resourceBigipLtmProfileRewriteRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + name := d.Id() + log.Printf("[INFO] Reading LTM rewrite profile config") + profile, err := client.GetRewriteProfile(name) + if err != nil { + return diag.FromErr(err) + } + if profile == nil { + d.SetId("") + return diag.FromErr(fmt.Errorf("[ERROR] LTM Rewrite Profile (%s) not found, removing from state", d.Id())) + } + log.Printf("[DEBUG] LTM rewrite profile:%+v", profile) + setRewriteProfileData(d, profile) + return nil +} + +func resourceBigipLtmProfileRewriteUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + name := d.Id() + profileConfig := &bigip.RewriteProfile{ + Name: name, + } + log.Println("[INFO] Updating LTM rewrite profile") + rewriteProfileConfig := getRewriteProfileConfig(d, profileConfig) + log.Printf("Config value:%+v", rewriteProfileConfig) + err := client.ModifyRewriteProfile(name, rewriteProfileConfig) + if err != nil { + return diag.FromErr(fmt.Errorf("error modifying LTM Rewrite Profile (%s): %s", name, err)) + } + return resourceBigipLtmProfileRewriteRead(ctx, d, meta) +} + +func resourceBigipLtmProfileRewriteDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + name := d.Id() + log.Println("[INFO] Deleting LTM Rewrite Profile " + name) + err := client.DeleteRewriteProfile(name) + if err != nil { + log.Printf("[ERROR] Unable to Delete LTM Rewrite Profile (%s) (%v) ", name, err) + return diag.FromErr(err) + } + d.SetId("") + return nil +} + +func setRewriteProfileData(d *schema.ResourceData, data *bigip.RewriteProfile) diag.Diagnostics { + _ = d.Set("name", data.FullPath) + _ = d.Set("defaults_from", data.DefaultsFrom) + _ = d.Set("rewrite_mode", data.Mode) + _ = d.Set("ca_file", data.CaFile) + _ = d.Set("crl_file", data.CrlFile) + _ = d.Set("signing_cert", data.SigningCert) + _ = d.Set("signing_key", data.SigningKey) + _ = d.Set("signing_key_password", data.SigningKeyPass) + _ = d.Set("cache_type", data.CachingType) + _ = d.Set("split_tunneling", data.SplitTunnel) + _ = d.Set("rewrite_list", data.RewriteList) + _ = d.Set("bypass_list", data.BypassList) + var reqList []interface{} + req := make(map[string]interface{}) + req["insert_xfwd_for"] = data.Request.XfwdFor + req["insert_xfwd_host"] = data.Request.XfwdHost + req["insert_xfwd_protocol"] = data.Request.XfwdProtocol + req["rewrite_headers"] = data.Request.RewriteHeaders + reqList = append(reqList, req) + _ = d.Set("request", reqList) + var resList []interface{} + res := make(map[string]interface{}) + res["rewrite_content"] = data.Response.RewriteContent + res["rewrite_headers"] = data.Response.RewriteHeaders + resList = append(resList, res) + _ = d.Set("response", resList) + cookies := make([]interface{}, len(data.Cookies)) + for i, v := range data.Cookies { + obj := make(map[string]interface{}) + if v.Name != "" { + obj["rule_name"] = v.Name + } + if v.Client.Domain != "" { + obj["client_domain"] = v.Client.Domain + } + if v.Client.Path != "" { + obj["client_path"] = v.Client.Path + } + if v.Server.Domain != "" { + obj["server_domain"] = v.Server.Domain + } + if v.Server.Path != "" { + obj["server_path"] = v.Server.Path + } + cookies[i] = obj + } + err := d.Set("cookie_rules", cookies) + if err != nil { + return diag.FromErr(err) + } + return nil +} + +func getRewriteProfileConfig(d *schema.ResourceData, config *bigip.RewriteProfile) *bigip.RewriteProfile { + config.DefaultsFrom = d.Get("defaults_from").(string) + // config.Partition = d.Get("partition").(string) + config.Mode = d.Get("rewrite_mode").(string) + config.CaFile = d.Get("ca_file").(string) + config.CrlFile = d.Get("crl_file").(string) + config.SigningCert = d.Get("signing_cert").(string) + config.SigningKey = d.Get("signing_key").(string) + config.SigningKeyPass = d.Get("signing_key_password").(string) + config.CachingType = d.Get("cache_type").(string) + config.SplitTunnel = d.Get("split_tunneling").(string) + config.RewriteList = listToStringSlice(d.Get("rewrite_list").([]interface{})) + config.BypassList = listToStringSlice(d.Get("bypass_list").([]interface{})) + + if val, ok := d.GetOk("request"); ok { + var reqAttrs bigip.RewriteProfileRequestd + for _, item := range val.(*schema.Set).List() { + reqAttrs.XfwdFor = item.(map[string]interface{})["insert_xfwd_for"].(string) + reqAttrs.XfwdHost = item.(map[string]interface{})["insert_xfwd_host"].(string) + reqAttrs.XfwdProtocol = item.(map[string]interface{})["insert_xfwd_protocol"].(string) + reqAttrs.RewriteHeaders = item.(map[string]interface{})["rewrite_headers"].(string) + } + config.Request = reqAttrs + } + + if val, ok := d.GetOk("response"); ok { + var resAttrs bigip.RewriteProfileResponsed + for _, item := range val.(*schema.Set).List() { + resAttrs.RewriteContent = item.(map[string]interface{})["rewrite_content"].(string) + resAttrs.RewriteHeaders = item.(map[string]interface{})["rewrite_headers"].(string) + } + config.Response = resAttrs + } + + if val, ok := d.GetOk("cookie_rules"); ok { + var cookieRules []bigip.RewriteProfileCookieRules + for _, item := range val.(*schema.Set).List() { + cookieRule := bigip.RewriteProfileCookieRules{} + log.Printf("[DEBUG] Value:%+v", item.(map[string]interface{})["rule_name"].(string)) + cookieRule.Name = item.(map[string]interface{})["rule_name"].(string) + log.Printf("[DEBUG] Value:%+v", item.(map[string]interface{})["client_domain"].(string)) + cookieRule.Client.Domain = item.(map[string]interface{})["client_domain"].(string) + log.Printf("[DEBUG] Value:%+v", item.(map[string]interface{})["client_path"].(string)) + cookieRule.Client.Path = item.(map[string]interface{})["client_path"].(string) + log.Printf("[DEBUG] Value:%+v", item.(map[string]interface{})["server_domain"].(string)) + cookieRule.Server.Domain = item.(map[string]interface{})["server_domain"].(string) + log.Printf("[DEBUG] Value:%+v", item.(map[string]interface{})["server_path"].(string)) + cookieRule.Server.Path = item.(map[string]interface{})["server_path"].(string) + cookieRules = append(cookieRules, cookieRule) + } + config.Cookies = cookieRules + } + return config +} diff --git a/bigip/resource_bigip_ltm_profile_rewrite_test.go b/bigip/resource_bigip_ltm_profile_rewrite_test.go new file mode 100644 index 000000000..e0eca4e5d --- /dev/null +++ b/bigip/resource_bigip_ltm_profile_rewrite_test.go @@ -0,0 +1,223 @@ +/* +Copyright 2022 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" + "strings" + "testing" + + bigip "github.com/f5devcentral/go-bigip" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccLtmRewriteProfileCreateOnBigipTC1(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckLtmRewriteProfileDestroyed, + Steps: []resource.TestStep{ + { + Config: getLtmRewritePortalProfileConfig(), + Check: resource.ComposeTestCheckFunc( + testLtmRewriteProfileExists("/Common/tf_profile-tc1", true), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "rewrite_mode", "portal"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cache_type", "cache-img-css-js"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "ca_file", "/Common/ca-bundle.crt"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "split_tunneling", "false"), + ), + }, + }, + }) +} + +func getLtmRewritePortalProfileConfig() string { + return fmt.Sprintf(` + resource "bigip_ltm_profile_rewrite" "test-profile" { + name = "%v" + defaults_from = "/Common/rewrite" + rewrite_mode = "portal" + cache_type = "cache-img-css-js" + ca_file = "/Common/ca-bundle.crt" + signing_cert = "/Common/default.crt" + signing_key = "/Common/default.key" + split_tunneling = "false" + }`, "/Common/tf_profile-tc1") +} + +func TestAccLtmRewriteProfileCreateOnBigipTC2(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckLtmRewriteProfileDestroyed, + Steps: []resource.TestStep{ + { + Config: getLtmRewriteUriRewriteProfileConfig(), + Check: resource.ComposeTestCheckFunc( + testLtmRewriteProfileExists("/Common/tf_profile_translate", true), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "rewrite_mode", "uri-translation"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "request.0.insert_xfwd_for", "enabled"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "request.0.insert_xfwd_host", "disabled"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "request.0.insert_xfwd_protocol", "enabled"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.0.rule_name", "cookie1"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.0.client_domain", "wrong.com"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.0.client_path", "/this/"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.0.server_domain", "right.com"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.0.server_path", "/that/"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.1.rule_name", "cookie2"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.1.client_domain", "incorrect.com"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.1.client_path", "/this/"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.1.server_domain", "absolute.com"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.1.server_path", "/that/"), + ), + }, + }, + }) +} + +func TestAccLtmRewriteProfileCreateOnBigipTC3(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckLtmRewriteProfileDestroyed, + Steps: []resource.TestStep{ + { + Config: getLtmRewriteUriRewriteProfileConfig(), + Check: resource.ComposeTestCheckFunc( + testLtmRewriteProfileExists("/Common/tf_profile_translate", true), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "rewrite_mode", "uri-translation"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "request.0.insert_xfwd_for", "enabled"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "request.0.insert_xfwd_host", "disabled"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "request.0.insert_xfwd_protocol", "enabled"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.0.rule_name", "cookie1"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.0.client_domain", "wrong.com"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.0.client_path", "/this/"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.0.server_domain", "right.com"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.0.server_path", "/that/"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.1.rule_name", "cookie2"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.1.client_domain", "incorrect.com"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.1.client_path", "/this/"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.1.server_domain", "absolute.com"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.1.server_path", "/that/"), + ), + }, + { + Config: getLtmRewriteUriRewriteProfileConfigChanged(), + Check: resource.ComposeTestCheckFunc( + testLtmRewriteProfileExists("/Common/tf_profile_translate", true), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "request.0.insert_xfwd_for", "disabled"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "request.0.insert_xfwd_host", "enabled"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "request.0.insert_xfwd_protocol", "disabled"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.0.rule_name", "cookie1"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.0.client_domain", "totallywrong.com"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.0.client_path", "/these/"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.0.server_domain", "totallyright.com"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.test-profile", "cookie_rules.0.server_path", "/those/"), + ), + }, + }, + }) +} + +func getLtmRewriteUriRewriteProfileConfig() string { + return fmt.Sprintf(` + resource "bigip_ltm_profile_rewrite" "test-profile2" { + name = "%v" + defaults_from = "/Common/rewrite" + rewrite_mode = "uri-translation" + + request { + insert_xfwd_for = "enabled" + insert_xfwd_host = "disabled" + insert_xfwd_protocol = "enabled" + } + + cookie_rules { + rule_name = "cookie1" + client_domain = "wrong.com" + client_path = "/this/" + server_domain = "right.com" + server_path = "/that/" + } + + cookie_rules { + rule_name = "cookie2" + client_domain = "incorrect.com" + client_path = "/this/" + server_domain = "absolute.com" + server_path = "/that/" + } + } +`, "/Common/tf_profile_translate") +} + +func getLtmRewriteUriRewriteProfileConfigChanged() string { + return fmt.Sprintf(` + resource "bigip_ltm_profile_rewrite" "test-profile2" { + name = "%v" + + request { + insert_xfwd_for = "disabled" + insert_xfwd_host = "enabled" + insert_xfwd_protocol = "disabled" + } + + cookie_rules { + rule_name = "cookie1" + client_domain = "totallywrong.com" + client_path = "/these/" + server_domain = "totallyright.com" + server_path = "/those/" + } + } +`, "/Common/tf_profile_translate") +} + +func testLtmRewriteProfileExists(name string, exists bool) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*bigip.BigIP) + p, err := client.GetRewriteProfile(name) + if err != nil { + return err + } + if exists && p == nil { + return fmt.Errorf("rewrite profile %s was not created", name) + } + if !exists && p != nil { + return fmt.Errorf("rewrite profile %s still exists", name) + } + return nil + } +} + +func testCheckLtmRewriteProfileDestroyed(s *terraform.State) error { + client := testAccProvider.Meta().(*bigip.BigIP) + for _, rs := range s.RootModule().Resources { + if rs.Type != "bigip_ltm_profile_rewrite" { + continue + } + name := rs.Primary.ID + p, err := client.GetRewriteProfile(name) + if err != nil { + if strings.Contains(err.Error(), "not found") { + return nil + } + return err + } + if p != nil { + return fmt.Errorf("Ltm Rewrite Profile %s not destroyed.", name) + } + } + return nil +} diff --git a/bigip/resource_bigip_ltm_profile_rewrite_uri_rules.go b/bigip/resource_bigip_ltm_profile_rewrite_uri_rules.go new file mode 100644 index 000000000..11a2ecdfd --- /dev/null +++ b/bigip/resource_bigip_ltm_profile_rewrite_uri_rules.go @@ -0,0 +1,240 @@ +/* +Original work from https://github.com/DealerDotCom/terraform-provider-bigip +Modifications Copyright 2024 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" + "fmt" + bigip "github.com/f5devcentral/go-bigip" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "log" +) + +func resourceBigipLtmRewriteProfileUriRules() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceBigipLtmRewriteProfileUriRuleCreate, + ReadContext: resourceBigipLtmProfileRewriteUriRuleRead, + UpdateContext: resourceBigipLtmProfileRewriteUriRuleUpdate, + DeleteContext: resourceBigipLtmProfileRewriteUriRuleDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + Schema: map[string]*schema.Schema{ + "profile_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Name of the rewrite profile.", + ValidateFunc: validateF5NameWithDirectory, + }, + "rule_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Specifies the name of the uri rule.", + }, + "rule_type": { + Type: schema.TypeString, + Optional: true, + Default: "both", + Description: "Specifies the type of the uri rule.", + ValidateFunc: validation.StringInSlice([]string{"request", "response", "both"}, false), + }, + "client": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "host": { + Type: schema.TypeString, + Required: true, + Description: "Host part of the uri, e.g. www.foo.com.", + }, + "path": { + Type: schema.TypeString, + Optional: true, + Default: "/", + Description: "Path part of the uri, when unspecified a trailing `/` is assumed.", + }, + "scheme": { + Type: schema.TypeString, + Required: true, + Description: "Scheme part of the uri, e.g. https, ftp etc.", + }, + "port": { + Type: schema.TypeString, + Default: "none", + Optional: true, + Description: "Port part of the uri, when not defined 'none' value is assumed.", + }, + }, + }, + }, + "server": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "host": { + Type: schema.TypeString, + Required: true, + Description: "Host part of the uri, e.g. www.foo.com", + }, + "path": { + Type: schema.TypeString, + Optional: true, + Default: "/", + Description: "Path part of the uri, when unspecified a trailing `/` is assumed.", + }, + "scheme": { + Type: schema.TypeString, + Required: true, + Description: "Scheme part of the uri, e.g. https, ftp etc.", + }, + "port": { + Type: schema.TypeString, + Default: "none", + Optional: true, + Description: "Port part of the uri, when not defined 'none' value is assumed.", + }, + }, + }, + }, + }, + } +} + +func resourceBigipLtmRewriteProfileUriRuleCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + + profileName := d.Get("profile_name").(string) + ruleName := d.Get("rule_name").(string) + pss := &bigip.RewriteProfileUriRule{ + Name: ruleName, + } + + log.Printf("[INFO] Creating LTM rewrite URI rule") + config := getUriRulesConfig(d, pss) + log.Printf("Config value:%+v", config) + + log.Printf("[INFO] Creating LTM rewrite URI rule") + err := client.AddRewriteProfileUriRule(profileName, config) + if err != nil { + log.Printf("[ERROR] Unable to Create Rewrite URI Rule for profile %s %v :", profileName, err) + return diag.FromErr(err) + } + d.SetId(ruleName) + + return resourceBigipLtmProfileRewriteUriRuleRead(ctx, d, meta) +} +func resourceBigipLtmProfileRewriteUriRuleRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + + ruleName := d.Id() + profileName := d.Get("profile_name").(string) + + log.Printf("[INFO] Reading LTM rewrite URI rule: %s", ruleName) + rules, err := client.GetRewriteProfileUriRule(profileName, ruleName) + if err != nil { + return diag.FromErr(err) + } + if rules == nil { + d.SetId("") + return diag.FromErr(fmt.Errorf("[ERROR] LTM Rewrite Profile URI rule (%s) not found, removing from state", d.Id())) + } + log.Printf("[DEBUG] LTM rewrite profile URI rule:%+v", rules) + + setUriRulesData(d, rules) + return nil +} + +func resourceBigipLtmProfileRewriteUriRuleUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + ruleName := d.Id() + profileName := d.Get("profile_name").(string) + uriConfig := &bigip.RewriteProfileUriRule{ + Name: ruleName, + } + log.Println("[INFO] Updating LTM rewrite URI rule") + uriRules := getUriRulesConfig(d, uriConfig) + log.Printf("Config value:%+v", uriRules) + err := client.ModifyRewriteProfileUriRule(profileName, ruleName, uriRules) + if err != nil { + return diag.FromErr(fmt.Errorf("error modifying LTM Rewrite URI rule (%s): %s", ruleName, err)) + } + return resourceBigipLtmProfileRewriteRead(ctx, d, meta) +} + +func resourceBigipLtmProfileRewriteUriRuleDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + ruleName := d.Id() + profileName := d.Get("profile_name").(string) + log.Println("[INFO] Deleting LTM Rewrite Profile URI rule " + ruleName) + err := client.DeleteRewriteProfileUriRule(profileName, ruleName) + if err != nil { + log.Printf("[ERROR] Unable to Delete LTM Rewrite Profile URI rule (%s) (%v) ", ruleName, err) + return diag.FromErr(err) + } + d.SetId("") + return nil +} + +func setUriRulesData(d *schema.ResourceData, data *bigip.RewriteProfileUriRule) diag.Diagnostics { + _ = d.Set("rule_name", data.Name) + _ = d.Set("rule_type", data.Type) + + var clList []interface{} + cl := make(map[string]interface{}) + cl["host"] = data.Client.Host + cl["path"] = data.Client.Path + cl["scheme"] = data.Client.Scheme + cl["port"] = data.Client.Port + clList = append(clList, cl) + _ = d.Set("client", clList) + + var srvList []interface{} + srv := make(map[string]interface{}) + srv["host"] = data.Server.Host + srv["path"] = data.Server.Path + srv["scheme"] = data.Server.Scheme + srv["port"] = data.Server.Port + srvList = append(srvList, srv) + _ = d.Set("server", srvList) + + return nil +} + +func getUriRulesConfig(d *schema.ResourceData, config *bigip.RewriteProfileUriRule) *bigip.RewriteProfileUriRule { + config.Type = d.Get("rule_type").(string) + client := d.Get("client") + server := d.Get("server") + + for _, item := range client.(*schema.Set).List() { + log.Printf("[DEBUG] Value:%+v", item.(map[string]interface{})["host"].(string)) + config.Client.Host = item.(map[string]interface{})["host"].(string) + log.Printf("[DEBUG] Value:%+v", item.(map[string]interface{})["path"].(string)) + config.Client.Path = item.(map[string]interface{})["path"].(string) + log.Printf("[DEBUG] Value:%+v", item.(map[string]interface{})["scheme"].(string)) + config.Client.Scheme = item.(map[string]interface{})["scheme"].(string) + log.Printf("[DEBUG] Value:%+v", item.(map[string]interface{})["port"].(string)) + config.Client.Port = item.(map[string]interface{})["port"].(string) + } + + for _, item := range server.(*schema.Set).List() { + log.Printf("[DEBUG] Value:%+v", item.(map[string]interface{})["host"].(string)) + config.Server.Host = item.(map[string]interface{})["host"].(string) + log.Printf("[DEBUG] Value:%+v", item.(map[string]interface{})["path"].(string)) + config.Server.Path = item.(map[string]interface{})["path"].(string) + log.Printf("[DEBUG] Value:%+v", item.(map[string]interface{})["scheme"].(string)) + config.Server.Scheme = item.(map[string]interface{})["scheme"].(string) + log.Printf("[DEBUG] Value:%+v", item.(map[string]interface{})["port"].(string)) + config.Server.Port = item.(map[string]interface{})["port"].(string) + } + return config +} diff --git a/bigip/resource_bigip_ltm_profile_rewrite_uri_rules_test.go b/bigip/resource_bigip_ltm_profile_rewrite_uri_rules_test.go new file mode 100644 index 000000000..4994f3fde --- /dev/null +++ b/bigip/resource_bigip_ltm_profile_rewrite_uri_rules_test.go @@ -0,0 +1,118 @@ +/* +Copyright 2022 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" + "github.com/f5devcentral/go-bigip" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +var rewPorfile = fmt.Sprintf("/%s/%s", TestPartition, "tf_profile") +var rule1 = fmt.Sprintf("tf_rule") + +var TestProfileResource = ` +resource "bigip_ltm_profile_rewrite" "tftest" { + name = "` + rewPorfile + `" + defaults_from = "/Common/rewrite" + rewrite_mode = "uri-translation" + + request { + insert_xfwd_for = "enabled" + insert_xfwd_host = "disabled" + insert_xfwd_protocol = "enabled" + rewrite_headers = "disabled" + } + + response { + rewrite_content = "enabled" + rewrite_headers = "disabled" + } + + cookie_rules { + rule_name = "cookie1" + client_domain = "wrong.com" + client_path = "/this/" + server_domain = "wrong.com" + server_path = "/this/" + } +} + +resource "bigip_ltm_profile_rewrite_uri_rules" "tftestrule1" { + profile_name = "` + rewPorfile + `" + rule_name = "` + rule1 + `"" + rule_type = "request" + + client { + host = "www.foo.com" + scheme = "https" + } + + server { + host = "www.bar.com" + path = "/this/" + scheme = "https" + port = "8888" + } +} +` + +func TestAccLtmRewriteProfileUriRulesCreateOnBigip(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckLtmRewriteProfileDestroyed, + Steps: []resource.TestStep{ + { + Config: TestProfileResource, + Check: resource.ComposeTestCheckFunc( + testLtmRewriteProfileExists(rewPorfile, true), + testLtmRewriteProfileUriRuleExists(rewPorfile, rule1, true), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.tftest", "rewrite_mode", "uri-translation"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.tftest", "request.0.insert_xfwd_for", "enabled"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.tftest", "request.0.insert_xfwd_host", "disabled"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.tftest", "request.0.insert_xfwd_protocol", "enabled"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.tftest", "cookie_rules.0.rule_name", "cookie1"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.tftest", "cookie_rules.0.client_domain", "wrong.com"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.tftest", "cookie_rules.0.client_path", "/this/"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.tftest", "cookie_rules.0.server_domain", "right.com"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite.tftest", "cookie_rules.0.server_path", "/that/"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite_uri_rules.tftestrule1", "rule_name", rule1), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite_uri_rules.tftestrule1", "rule_type", "request"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite_uri_rules.tftestrule1", "client.0.host", "www.foo.com"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite_uri_rules.tftestrule1", "client.0.scheme", "https"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite_uri_rules.tftestrule1", "server.0.host", "www.bar.com"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite_uri_rules.tftestrule1", "server.0.path", "/this/"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite_uri_rules.tftestrule1", "server.0.scheme", "https"), + resource.TestCheckResourceAttr("bigip_ltm_profile_rewrite_uri_rules.tftestrule1", "server.0.port", "8888"), + ), + }, + }, + }) +} + +func testLtmRewriteProfileUriRuleExists(profile string, uri string, exists bool) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*bigip.BigIP) + p, err := client.GetRewriteProfileUriRule(profile, uri) + if err != nil { + return err + } + if exists && p != nil { + return fmt.Errorf("rewrite profile uri rule %s was not created", uri) + } + if !exists && p != nil { + return fmt.Errorf("rewrite profile uri rule %s still exists", uri) + } + return nil + } +} diff --git a/docs/resources/bigip_ltm_profile_rewrite.md b/docs/resources/bigip_ltm_profile_rewrite.md new file mode 100644 index 000000000..399cadcbb --- /dev/null +++ b/docs/resources/bigip_ltm_profile_rewrite.md @@ -0,0 +1,111 @@ +--- +layout: "bigip" +page_title: "BIG-IP: bigip_ltm_profile_rewrite" +subcategory: "Local Traffic Manager(LTM)" +description: |- + Provides details about bigip_ltm_profile_rewrite resource +--- + +# bigip\_ltm\_rewrite\_profile + +`bigip_ltm_rewrite_profile` Configures ltm policies to manage traffic assigned to a virtual server + +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/test-profile`. + +## Example Usage + +```hcl + +resource "bigip_ltm_profile_rewrite" "test-profile" { + name = "/Common/tf_profile" + defaults_from = "/Common/rewrite" + bypass_list = ["http://notouch.com"] + rewrite_list = ["http://some.com"] + rewrite_mode = "portal" + cache_type = "cache-img-css-js" + ca_file = "/Common/ca-bundle.crt" + crl_file = "none" + signing_cert = "/Common/default.crt" + signing_key = "/Common/default.key" + split_tunneling = "true" +} + +resource "bigip_ltm_profile_rewrite" "test-profile2" { + name = "/Common/tf_profile_translate" + defaults_from = "/Common/rewrite" + rewrite_mode = "uri-translation" + + request { + insert_xfwd_for = "enabled" + insert_xfwd_host = "disabled" + insert_xfwd_protocol = "enabled" + rewrite_headers = "disabled" + } + + response { + rewrite_content = "enabled" + rewrite_headers = "disabled" + } + + cookie_rules { + rule_name = "cookie1" + client_domain = "wrong.com" + client_path = "/this/" + server_domain = "wrong.com" + server_path = "/this/" + } + + cookie_rules { + rule_name = "cookie2" + client_domain = "incorrect.com" + client_path = "/this/" + server_domain = "absolute.com" + server_path = "/this/" + } +} +``` + +## Argument Reference + +* `name`- (Required) Name of the rewrite profile. ( profile name should be in full path which is combination of partition and profile name ) + +* `partition` - (optional,type `string`) Specifies the partition to create resource. + +* `defaults_from` - (optional,type `string`) Specifies the profile from which this profile inherits settings. The default is the system-supplied `rewrite` profile. + +* `bypass_list` - (Optional,type `list`) Specifies a list of URIs to bypass inside a web page when the page is accessed using Portal Access. + +* `cache_type` - (Optional,type `string`) Specifies the type of Client caching. Valid choices are: `cache-css-js, cache-all, no-cache, cache-img-css-js`. Default value: `cache-img-css-js` + +* `ca_file` - (Optional, type `string`) Specifies a CA against which to verify signed Java applets signatures. (name should be in full path which is combination of partition and CA file name ) + +* `crl_file` - (Optional, type `string`) Specifies a CRL against which to verify signed Java applets signature certificates. The default option is `none`. + +* `signing_cert` - (Optional, type `string`) Specifies a certificate to use for re-signing of signed Java applets after patching. (name should be in full path which is combination of partition and certificate name ) + +* `signing_key` - (Optional, type `string`) Specifies a certificate to use for re-signing of signed Java applets after patching. (name should be in full path which is combination of partition and key name ) + +* `signing_key_password` - (Optional, type `string`) Specifies a pass phrase to use for encrypting the private signing key. + +* `split_tunneling` - (Optional,type `string`) Specifies the type of Client caching. Valid choices are: `true, false` + +* `rewrite_list` - (Optional,type `list`) Specifies a list of URIs to rewrite inside a web page when the page is accessed using Portal Access. + +* `rewrite_mode` - (Required,type `string`) Specifies the type of Client caching. Valid choices are: `portal, uri-translation` + +* `request` - (Optional,type `set`) Block type. Each request is block type with following arguments. + * `insert_xfwd_for` - (Optional,type `string`) Enable to add the X-Forwarded For (XFF) header, to specify the originating IP address of the client. Valid choices are: `enabled, disabled` + * `insert_xfwd_host` - (Optional,type `string`) Enable to add the X-Forwarded Host header, to specify the originating host of the client. Valid choices are: `enabled, disabled` + * `insert_xfwd_protocol` - (Optional,type `string`) Enable to add the X-Forwarded Proto header, to specify the originating protocol of the client. Valid choices are: `enabled, disabled` + * `rewrite_headers` - (Optional,type `string`) Enable to rewrite headers in Request settings. Valid choices are: `enabled, disabled` + +* `response` - (Optional,type `set`) Block type. Each request is block type with following arguments. + * `rewrite_content` - (Optional,type `string`) Enable to rewrite links in content in the response. Valid choices are: `enabled, disabled` + * `rewrite_headers` - (Optional,type `string`) Enable to rewrite headers in the response. Valid choices are: `enabled, disabled` + +* `cookie_rules` - (Optional,type `set`) Specifies the cookie rewrite rules. Block type. Each request is block type with following arguments. + * `rule_name` - (Required,type `string`) Name of the cookie rewrite rule. + * `client_domain` - (Required,type `string`) + * `client_path` - (Required,type `string`) + * `server_domain` - (Required,type `string`) + * `server_path` - (Required,type `string`) diff --git a/docs/resources/bigip_ltm_profile_rewrite_uri_rules.md b/docs/resources/bigip_ltm_profile_rewrite_uri_rules.md new file mode 100644 index 000000000..79da0893d --- /dev/null +++ b/docs/resources/bigip_ltm_profile_rewrite_uri_rules.md @@ -0,0 +1,78 @@ +--- +layout: "bigip" +page_title: "BIG-IP: bigip_ltm_profile_rewrite_uri_rules" +subcategory: "Local Traffic Manager(LTM)" +description: |- + Provides details about bigip_ltm_profile_rewrite_uri_rules resource +--- + +# bigip\_ltm\_rewrite\_profile_\uri\_rules + +`bigip_ltm_profile_rewrite_uri_rules` Configures uri rewrite rules attached to the ltm rewrite profile + +## Example Usage + +```hcl + +resource "bigip_ltm_profile_rewrite" "tftest" { + name = "/Common/tf_profile" + defaults_from = "/Common/rewrite" + rewrite_mode = "uri-translation" +} + +resource "bigip_ltm_profile_rewrite_uri_rules" "tftestrule1" { + profile_name = bigip_ltm_profile_rewrite.tftest.name + rule_name = "tf_rule" + rule_type = "request" + + client { + host = "www.foo.com" + scheme = "https" + } + + server { + host = "www.bar.com" + path = "/this/" + scheme = "https" + port = "8888" + } +} + +resource "bigip_ltm_profile_rewrite_uri_rules" "tftestrule2" { + profile_name = bigip_ltm_profile_rewrite.tftest.name + rule_name = "tf_rule2" + + client { + host = "www.baz.com" + path = "/that/" + scheme = "ftp" + port = "8888" + } + + server { + host = "www.buz.com" + path = "/those/" + scheme = "ftps" + } +} +``` + +## Argument Reference + +* `profile_name`- (Required, type `string`) Name of the rewrite profile. ( policy name should be in full path which is combination of partition and policy name ) + +* `rule_name` - (Required, type `string`) Specifies the name of the uri rule. + +* `rule_type` - (Optional, type `string`) Specifies the type of the uri rule. Valid choices are: `request, response, both`. Default value is: `both` + +* `client` - (Optional,type `set`) Block type. Each request is block type with following arguments. + * `host` - (Required,type `string`) Host part of the uri, e.g. `www.foo.com`. + * `path` - (Optional,type `string`) Path part of the uri, must always end with `/`. Default value is: `/` + * `scheme` - (Required,type `string`) Scheme part of the uri, e.g. `https`, `ftp`. + * `port` - (Optional,type `string`) Port part of the uri. Default value is: `none` + +* `server` - (Optional,type `set`) Block type. Each request is block type with following arguments. + * `host` - (Required,type `string`) Host part of the uri, e.g. `www.foo.com`. + * `path` - (Optional,type `string`) Path part of the uri, must always end with `/`. Default value is: `/` + * `scheme` - (Required,type `string`) Scheme part of the uri, e.g. `https`, `ftp`. + * `port` - (Optional,type `string`) Port part of the uri. Default value is: `none` diff --git a/vendor/github.com/f5devcentral/go-bigip/ltm.go b/vendor/github.com/f5devcentral/go-bigip/ltm.go index f37841f98..592e946d9 100644 --- a/vendor/github.com/f5devcentral/go-bigip/ltm.go +++ b/vendor/github.com/f5devcentral/go-bigip/ltm.go @@ -1935,6 +1935,68 @@ type CipherRule struct { SignatureAlgorithms string `json:"signatureAlgorithms,omitempty"` } +type RewriteProfile struct { + Name string `json:"name,omitempty"` + Partition string `json:"partition,omitempty"` + FullPath string `json:"fullPath,omitempty"` + DefaultsFrom string `json:"defaultsFrom,omitempty"` + AppService string `json:"appService,omitempty"` + Mode string `json:"rewriteMode,omitempty"` + CaFile string `json:"javaCaFile,omitempty"` + CrlFile string `json:"javaCrl,omitempty"` + CachingType string `json:"clientCachingType,omitempty"` + SigningCert string `json:"javaSigner,omitempty"` + SigningKey string `json:"javaSignKey,omitempty"` + SigningKeyPass string `json:"javaSignKeyPassphrase,omitempty"` + SplitTunnel string `json:"splitTunneling,omitempty"` + RewriteList []string `json:"rewriteList,omitempty"` + BypassList []string `json:"bypassList,omitempty"` + Request RewriteProfileRequestd `json:"request,omitempty"` + Response RewriteProfileResponsed `json:"response,omitempty"` + Cookies []RewriteProfileCookieRules `json:"setCookieRules,omitempty"` +} + +type RewriteProfileRequestd struct { + XfwdFor string `json:"insertXforwardedFor,omitempty"` + XfwdHost string `json:"insertXforwardedHost,omitempty"` + XfwdProtocol string `json:"insertXforwardedProto,omitempty"` + RewriteHeaders string `json:"rewriteHeaders,omitempty"` +} + +type RewriteProfileResponsed struct { + RewriteContent string `json:"rewriteContent,omitempty"` + RewriteHeaders string `json:"rewriteHeaders,omitempty"` +} + +type RewriteProfileUriRules struct { + Uri []RewriteProfileUriRule `json:"items,omitempty"` +} + +type RewriteProfileUriRule struct { + Name string `json:"name,omitempty"` + Type string `json:"type,omitempty"` + Client RewriteProfileUrlClSrv`json:"client,omitempty"` + Server RewriteProfileUrlClSrv `json:"server,omitempty"` +} + +type RewriteProfileUrlClSrv struct { + Host string `json:"host,omitempty"` + Path string `json:"path,omitempty"` + Port string `json:"port,omitempty"` + Scheme string `json:"scheme,omitempty"` +} + +type RewriteProfileCookieClSrv struct { + Domain string `json:"domain,omitempty"` + Path string `json:"path,omitempty"` +} + +type RewriteProfileCookieRules struct { + Name string `json:"name,omitempty"` + Client RewriteProfileCookieClSrv `json:"client,omitempty"` + Server RewriteProfileCookieClSrv `json:"server,omitempty"` +} + const ( uriLtm = "ltm" uriNode = "node" @@ -1960,6 +2022,8 @@ const ( CONTEXT_SERVER = "serverside" CONTEXT_CLIENT = "clientside" CONTEXT_ALL = "all" + uriRewrite = "rewrite" + uriRewriteRules = "uri-rules" uriTcp = "tcp" uriFtp = "ftp" uriFasthttp = "fasthttp" @@ -2022,6 +2086,64 @@ var cidr = map[string]string{ "32": "255.255.255.255", } +// AddRewriteProfile creates ltm rewrite profile on the BIG-IP system. +func (b *BigIP) AddRewriteProfile(config *RewriteProfile) error { + return b.post(config, uriLtm, uriProfile, uriRewrite) +} + +// GetRewriteProfile gets a rewrite profile by name. Returns nil if the rewrite profile does not exist +func (b *BigIP) GetRewriteProfile(name string) (*RewriteProfile, error) { + var rewriteProfile RewriteProfile + err, ok := b.getForEntity(&rewriteProfile, uriLtm, uriProfile, uriRewrite, name) + if err != nil { + return nil, err + } + if !ok { + return nil, nil + } + + return &rewriteProfile, nil +} + +// DeleteRewriteProfile removes a rewrite profile. +func (b *BigIP) DeleteRewriteProfile(name string) error { + return b.delete(uriLtm, uriProfile, uriRewrite, name) +} + +// ModifyRewriteProfile allows you to change any attribute of a rewrite profile. +// Fields that can be modified are referenced in the RewriteProfile struct. +func (b *BigIP) ModifyRewriteProfile(name string, config *RewriteProfile) error { + return b.patch(config, uriLtm, uriProfile, uriRewrite, name) +} + +// GetRewriteProfileUrlRule returns an uri rule associated with rewrite profile. +func (b *BigIP) GetRewriteProfileUriRule(profile_name string, rule_name string) (*RewriteProfileUriRule, error) { + var urlRule RewriteProfileUriRule + err, _ := b.getForEntity(&urlRule, uriLtm, uriProfile, uriRewrite, profile_name, uriRewriteRules, rule_name) + if err != nil { + return nil, err + } + + return &urlRule, nil +} + +// AddRewriteProfile creates ltm rewrite profile on the BIG-IP system. +func (b *BigIP) AddRewriteProfileUriRule(name string, config *RewriteProfileUriRule) error { + return b.post(config, uriLtm, uriProfile, uriRewrite, name, uriRewriteRules) +} + +// ModifyRewriteProfileUrlRule allows you to change any attribute of an uri rule of rewrite profile. +// Fields that can be modified are referenced in the RewriteProfileUriRule struct. +func (b *BigIP) ModifyRewriteProfileUriRule(profile_name string, rule_name string, config *RewriteProfileUriRule) error { + return b.patch(config, uriLtm, uriProfile, uriRewrite, profile_name, uriRewriteRules, rule_name) +} + +// DeleteRewriteProfileUrlRule removes an url-rule in rewrite profile. +func (b *BigIP) DeleteRewriteProfileUriRule(profile_name string, rule_name string) error { + return b.delete(uriLtm, uriProfile, uriRewrite, profile_name, uriRewriteRules, rule_name) +} + + // SnatPools returns a list of snatpools. func (b *BigIP) SnatPools() (*SnatPools, error) { var snatPools SnatPools