From 99830432ed71f72fb2fe66c274983828ff710512 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 15:48:52 +0000 Subject: [PATCH 1/4] Bump crazy-max/ghaction-import-gpg from 6.1.0 to 6.2.0 Bumps [crazy-max/ghaction-import-gpg](https://github.com/crazy-max/ghaction-import-gpg) from 6.1.0 to 6.2.0. - [Release notes](https://github.com/crazy-max/ghaction-import-gpg/releases) - [Commits](https://github.com/crazy-max/ghaction-import-gpg/compare/v6.1.0...v6.2.0) --- updated-dependencies: - dependency-name: crazy-max/ghaction-import-gpg dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 895ca695..a127abb3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,7 +33,7 @@ jobs: name: Import GPG key id: import_gpg # see https://github.com/hashicorp/terraform-provider-scaffolding/issues/22 - uses: crazy-max/ghaction-import-gpg@v6.1.0 + uses: crazy-max/ghaction-import-gpg@v6.2.0 with: # These secrets will need to be configured for the repository: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} From f8e206e380a0ff65661e4ddea6b2c763c044a4c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 15:55:39 +0000 Subject: [PATCH 2/4] Bump goreleaser/goreleaser-action from 6.0.0 to 6.1.0 Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 6.0.0 to 6.1.0. - [Release notes](https://github.com/goreleaser/goreleaser-action/releases) - [Commits](https://github.com/goreleaser/goreleaser-action/compare/v6.0.0...v6.1.0) --- updated-dependencies: - dependency-name: goreleaser/goreleaser-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 895ca695..b4f021ee 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,7 +40,7 @@ jobs: passphrase: ${{ secrets.PASSPHRASE }} - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v6.0.0 + uses: goreleaser/goreleaser-action@v6.1.0 with: version: v1.25.1 args: release --rm-dist From 8e7f51a6fa5f1e1de88109c32f739f4c020dd7df Mon Sep 17 00:00:00 2001 From: RavinderReddyF5 Date: Wed, 11 Dec 2024 13:45:57 +0530 Subject: [PATCH 3/4] adding bot defense profile --- bigip/provider.go | 1 + bigip/resource_bigip_saas_bot_defense.go | 209 ++++++++++++++++++ bigip/resource_bigip_saas_bot_defense_test.go | 89 ++++++++ .../github.com/f5devcentral/go-bigip/ltm.go | 128 +++++++++++ 4 files changed, 427 insertions(+) create mode 100644 bigip/resource_bigip_saas_bot_defense.go create mode 100644 bigip/resource_bigip_saas_bot_defense_test.go diff --git a/bigip/provider.go b/bigip/provider.go index 17f4dba3..030b008c 100644 --- a/bigip/provider.go +++ b/bigip/provider.go @@ -193,6 +193,7 @@ func Provider() *schema.Provider { "bigip_ltm_profile_bot_defense": resourceBigipLtmProfileBotDefense(), "bigip_ltm_profile_rewrite": resourceBigipLtmRewriteProfile(), "bigip_ltm_profile_rewrite_uri_rules": resourceBigipLtmRewriteProfileUriRules(), + "bigip_saas_bot_defense_profile": resourceBigipSaasBotDefenseProfile(), }, } p.ConfigureContextFunc = func(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { diff --git a/bigip/resource_bigip_saas_bot_defense.go b/bigip/resource_bigip_saas_bot_defense.go new file mode 100644 index 00000000..adb659bc --- /dev/null +++ b/bigip/resource_bigip_saas_bot_defense.go @@ -0,0 +1,209 @@ +/* +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" + "log" + + bigip "github.com/f5devcentral/go-bigip" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceBigipSaasBotDefenseProfile() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceBigipSaasBotDefenseProfileCreate, + ReadContext: resourceBigipSaasBotDefenseProfileRead, + UpdateContext: resourceBigipSaasBotDefenseProfileUpdate, + DeleteContext: resourceBigipSaasBotDefenseProfileDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Unique name for the Bot Defense profile", + ValidateFunc: validateF5NameWithDirectory, + }, + "defaults_from": { + Type: schema.TypeString, + Optional: true, + Default: "/Common/bd", + Description: "Specifies the profile from which this profile inherits settings. The default is the system-supplied `bd` profile", + ValidateFunc: validateF5Name, + }, + "description": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "User defined description for Bot Defense profile", + }, + "application_id": { + Type: schema.TypeString, + Required: true, + Description: "User defined description for Bot Defense profile", + }, + "tenant_id": { + Type: schema.TypeString, + Required: true, + Description: "User defined description for Bot Defense profile", + }, + "api_key": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + Description: "User defined description for Bot Defense profile", + }, + "shape_protection_pool": { + Type: schema.TypeString, + Required: true, + Description: "User defined description for Bot Defense profile", + }, + "ssl_profile": { + Type: schema.TypeString, + Required: true, + Description: "User defined description for Bot Defense profile", + }, + "protected_endpoints": { + Type: schema.TypeList, + Required: true, + Description: "User defined description for Bot Defense profile", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "User defined description for Bot Defense profile", + }, + "host": { + Type: schema.TypeString, + Required: true, + Description: "User defined description for Bot Defense profile", + }, + "endpoint": { + Type: schema.TypeString, + Required: true, + Description: "User defined description for Bot Defense profile", + }, + "post": { + Type: schema.TypeString, + Required: true, + Description: "User defined description for Bot Defense profile", + }, + }, + }, + }, + }, + } +} + +func resourceBigipSaasBotDefenseProfileCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + name := d.Get("name").(string) + log.Printf("[INFO] Creating Bot Defense Profile:%+v ", name) + pss := &bigip.SaasBotDefenseProfile{ + Name: name, + } + config := getSaasBotDefenseProfileConfig(d, pss) + log.Printf("[DEBUG] Bot Defense Profile config :%+v ", config) + err := client.AddSaasBotDefenseProfile(config) + if err != nil { + return diag.FromErr(err) + } + d.SetId(name) + return resourceBigipSaasBotDefenseProfileRead(ctx, d, meta) +} + +func resourceBigipSaasBotDefenseProfileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + log.Printf("[INFO] Reading Bot Defense Profile:%+v ", client) + name := d.Id() + log.Printf("[INFO] Reading Bot Defense Profile:%+v ", name) + botProfile, err := client.GetSaasBotDefenseProfile(name) + if err != nil { + return diag.FromErr(err) + } + log.Printf("[DEBUG] Bot Defense Profile config :%+v ", botProfile) + d.Set("name", botProfile.FullPath) + d.Set("defaults_from", botProfile.DefaultsFrom) + d.Set("description", botProfile.Description) + return nil +} + +func resourceBigipSaasBotDefenseProfileUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + name := d.Id() + log.Printf("[INFO] Updating Bot Defense Profile:%+v ", name) + pss := &bigip.SaasBotDefenseProfile{ + Name: name, + } + config := getSaasBotDefenseProfileConfig(d, pss) + + err := client.ModifySaasBotDefenseProfile(name, config) + if err != nil { + return diag.FromErr(err) + } + return resourceBigipSaasBotDefenseProfileRead(ctx, d, meta) +} + +func resourceBigipSaasBotDefenseProfileDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*bigip.BigIP) + + name := d.Id() + log.Println("[INFO] Deleting Bot Defense Profile " + name) + err := client.DeleteSaasBotDefenseProfile(name) + if err != nil { + return diag.FromErr(err) + } + d.SetId("") + return nil +} + +func getSaasBotDefenseProfileConfig(d *schema.ResourceData, config *bigip.SaasBotDefenseProfile) *bigip.SaasBotDefenseProfile { + config.Name = d.Get("name").(string) + config.DefaultsFrom = d.Get("defaults_from").(string) + config.Description = d.Get("description").(string) + config.ApplicationId = d.Get("application_id").(string) + config.TenantId = d.Get("tenant_id").(string) + config.ApiKey = d.Get("api_key").(string) + config.ShapeProtectionPool = d.Get("shape_protection_pool").(string) + config.SslProfile = d.Get("ssl_profile").(string) + var protectEndpoint []bigip.ProtectedEndpoint + for _, endpoint := range d.Get("protected_endpoints").([]interface{}) { + ep := endpoint.(map[string]interface{}) + protectEndpoint = append(protectEndpoint, bigip.ProtectedEndpoint{ + Name: ep["name"].(string), + Host: ep["host"].(string), + Endpoint: ep["endpoint"].(string), + Post: ep["post"].(string), + }) + } + config.ProtectedEndpointsReference.Items = protectEndpoint + log.Printf("[INFO][getSaasBotDefenseProfileConfig] config:%+v ", config) + return config +} + +// { +// "name": "/Common/bd-test", +// "applicationId": "89fb0bfcb4bf4c578fad9adb37ce3b19", +// "tenantId": "a-aavN9vaYOV", +// "apiKey": "49840d1dd6fa4c4d86c88762eb398eee", +// "shapeProtectionPool": "/Common/cs1.pool", +// "sslProfile": "/Common/cloud-service-default-ssl", +// "protectedEndpointsReference": { +// "items": [ +// { +// "name": "pe1", +// "host": "abc.com", +// "endpoint": "/login", +// "post": "enabled" +// } +// ] +// } +// } diff --git a/bigip/resource_bigip_saas_bot_defense_test.go b/bigip/resource_bigip_saas_bot_defense_test.go new file mode 100644 index 00000000..53f1d7fe --- /dev/null +++ b/bigip/resource_bigip_saas_bot_defense_test.go @@ -0,0 +1,89 @@ +package bigip + +import ( + "fmt" + "testing" + + bigip "github.com/f5devcentral/go-bigip" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +var resSaasBotDefenseName = "bigip_saas_bot_defense_profile" + +func TestAccBigipSaasBotDefenseProfileTC1(t *testing.T) { + t.Parallel() + var instName = "test-saas-bot-defense-tc1" + var TestBotDefenseName = fmt.Sprintf("/%s/%s", TestPartition, instName) + resFullName := fmt.Sprintf("%s.%s", resSaasBotDefenseName, instName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckSaasBotDefensesDestroyed, + Steps: []resource.TestStep{ + { + Config: testaccbigipSaasBotDefenseDefaultConfig(TestPartition, TestBotDefenseName, instName), + Check: resource.ComposeTestCheckFunc( + testCheckSaasBotDefenseExists(TestBotDefenseName), + resource.TestCheckResourceAttr(resFullName, "name", TestBotDefenseName), + resource.TestCheckResourceAttr(resFullName, "defaults_from", "/Common/bd"), + ), + Destroy: false, + }, + }, + }) +} + +func testCheckSaasBotDefenseExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*bigip.BigIP) + p, err := client.GetSaasBotDefenseProfile(name) + if err != nil { + return err + } + if p == nil { + return fmt.Errorf("BotDefense %s was not created ", name) + } + + return nil + } +} + +func testCheckSaasBotDefensesDestroyed(s *terraform.State) error { + client := testAccProvider.Meta().(*bigip.BigIP) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "bigip_saas_bot_defense_profile" { + continue + } + + name := rs.Primary.ID + BotDefense, err := client.GetSaasBotDefenseProfile(name) + if err != nil { + return nil + } + if BotDefense != nil { + return fmt.Errorf("BotDefense %s not destroyed. ", name) + } + } + return nil +} + +func testaccbigipSaasBotDefenseDefaultConfig(partition, profileName, resourceName string) string { + return fmt.Sprintf(`resource "bigip_saas_bot_defense_profile" "%[3]s" { + name = "%[2]s" + application_id = "89fb0bfcb4bf4c578fad9adb37ce3b19" + tenant_id = "a-aavN9vaYOV" + api_key = "49840d1dd6fa4c4d86c88762eb398eee" + shape_protection_pool = "/%[1]s/cs1.pool" + ssl_profile = "/%[1]s/cloud-service-default-ssl" + protected_endpoints { + name = "pe1" + host = "abc.com" + endpoint = "/login" + post = "enabled" + } +}`, partition, profileName, resourceName) +} diff --git a/vendor/github.com/f5devcentral/go-bigip/ltm.go b/vendor/github.com/f5devcentral/go-bigip/ltm.go index c82bc382..8e1f690e 100644 --- a/vendor/github.com/f5devcentral/go-bigip/ltm.go +++ b/vendor/github.com/f5devcentral/go-bigip/ltm.go @@ -2061,6 +2061,8 @@ const ( uriRequestLog = "request-log" uriSecurity = "security" uriBotDefense = "bot-defense" + uriSaas = "saas" + uriSaasBotDefense = "bd" ) var cidr = map[string]string{ @@ -4319,3 +4321,129 @@ func (b *BigIP) GetBotDefenseProfile(name string) (*BotDefenseProfile, error) { } return &botDefenseProfile, nil } + +// { +// "name": "/Common/bd-test", +// "applicationId": "89fb0bfcb4bf4c578fad9adb37ce3b19", +// "tenantId": "a-aavN9vaYOV", +// "apiKey": "49840d1dd6fa4c4d86c88762eb398eee", +// "shapeProtectionPool": "/Common/cs1.pool", +// "sslProfile": "/Common/cloud-service-default-ssl", +// "protectedEndpointsReference": { +// "items": [ +// { +// "name": "pe1", +// "host": "abc.com", +// "endpoint": "/login", +// "post": "enabled" +// } +// ] +// } +// } + +type SaasBotDefenseProfile struct { + Name string `json:"name,omitempty"` + Partition string `json:"partition,omitempty"` + ApiHostname string `json:"apiHostname,omitempty"` + ApiKey string `json:"apiKey,omitempty"` + ApplicationId string `json:"applicationId,omitempty"` + TenantId string `json:"tenantId,omitempty"` + FullPath string `json:"fullPath,omitempty"` + DefaultsFrom string `json:"defaultsFrom,omitempty"` + Description string `json:"description,omitempty"` + ShapeProtectionPool string `json:"shapeProtectionPool,omitempty"` + SslProfile string `json:"sslProfile,omitempty"` + ServiceLevel string `json:"serviceLevel,omitempty"` + LogLevel string `json:"logLevel,omitempty"` + TelemetryHeaderPrefix string `json:"telemetryHeaderPrefix,omitempty"` + TelemetryRequestBodySize int `json:"telemetryRequestBodySize,omitempty"` + TlsFingerprint string `json:"tlsFingerprint,omitempty"` + DeploymentEnvironment string `json:"deploymentEnvironment,omitempty"` + AllowBrowserAccess string `json:"allowBrowserAccess,omitempty"` + SourceOfClientIpAddress string `json:"sourceOfClientIpAddress,omitempty"` + UseSni string `json:"useSni,omitempty"` + UseProxy string `json:"useProxy,omitempty"` + IncludePostBody string `json:"includePostBody,omitempty"` + InjectJsInSpecificUrl string `json:"injectJsInSpecificUrl,omitempty"` + InjectTelemetryJsInBodyTag string `json:"injectTelemetryJsInBodyTag,omitempty"` + LocationForShapeJsInjection string `json:"locationForShapeJsInjection,omitempty"` + JsMode string `json:"jsMode,omitempty"` + ShapeJsUrlOrPath string `json:"shapeJsUrlOrPath,omitempty"` + ShapeApiResponseTimeout int `json:"shapeApiResponseTimeout,omitempty"` + ProxyCloseOnError string `json:"proxyCloseOnError,omitempty"` + ProxyRespondOnLoggingError string `json:"proxyRespondOnLoggingError,omitempty"` + ProxyResponse string `json:"proxyResponse,omitempty"` + ReportTransactionResult string `json:"reportTransactionResult,omitempty"` + MitigationHandler string `json:"mitigationHandler,omitempty"` + MobileApiHostname string `json:"mobileApiHostname,omitempty"` + MobileSdkConfigFetchUrlAndroid string `json:"mobileSdkConfigFetchUrlAndroid,omitempty"` + MobileSdkConfigFetchUrlIos string `json:"mobileSdkConfigFetchUrlIos,omitempty"` + MobileMitigationHandler string `json:"mobileMitigationHandler,omitempty"` + MobileApplicationsInScope string `json:"mobileApplicationsInScope,omitempty"` + MobileBlockResponseCode int `json:"mobileBlockResponseCode,omitempty"` + MobileBlockResponseContentType string `json:"mobileBlockResponseContentType,omitempty"` + MobileBlockResponseBody string `json:"mobileBlockResponseBody,omitempty"` + WebApplicationsInScope string `json:"webApplicationsInScope,omitempty"` + BigipHandlesJsInjections string `json:"bigipHandlesJsInjections,omitempty"` + BlockResponseBody string `json:"blockResponseBody,omitempty"` + BlockResponseCode int `json:"blockResponseCode,omitempty"` + BlockResponseContentType string `json:"blockResponseContentType,omitempty"` + CorsSupport string `json:"corsSupport,omitempty"` + ExcludeJsInjectionFromSpecificUrl string `json:"excludeJsInjectionFromSpecificUrl,omitempty"` + LogRequestLoggingErrors string `json:"logRequestLoggingErrors,omitempty"` + LogResponseByDefault string `json:"logResponseByDefault,omitempty"` + LogResponseLoggingErrors string `json:"logResponseLoggingErrors,omitempty"` + RequestLogging string `json:"requestLogging,omitempty"` + ResponseLogging string `json:"responseLogging,omitempty"` + LogPublisher string `json:"logPublisher,omitempty"` + RedirectResponseCode int `json:"redirectResponseCode,omitempty"` + MobileIncludePostBody string `json:"mobileIncludePostBody,omitempty"` + ProtectedEndpointsReference struct { + Items []ProtectedEndpoint `json:"items,omitempty"` + } `json:"protectedEndpointsReference,omitempty"` +} + +// type SaasBotDefense struct { +// Name string `json:"name,omitempty"` +// ApplicationId string `json:"applicationId,omitempty"` +// TenantId string `json:"tenantId,omitempty"` +// ApiKey string `json:"apiKey,omitempty"` +// ShapeProtectionPool string `json:"shapeProtectionPool,omitempty"` +// SslProfile string `json:"sslProfile,omitempty"` +// ProtectedEndpoints []ProtectedEndpoint `json:"protectedEndpointsReference,omitempty"` +// } + +type ProtectedEndpoint struct { + Name string `json:"name,omitempty"` + Host string `json:"host,omitempty"` + Endpoint string `json:"endpoint,omitempty"` + Post string `json:"post,omitempty"` +} + +// AddSaasBotDefenseProfile creates a new Saas Bot Defense profile on the BIG-IP system. +func (b *BigIP) AddSaasBotDefenseProfile(config *SaasBotDefenseProfile) error { + return b.post(config, uriSaas, uriSaasBotDefense, uriProfile) +} + +// DeleteSaasBotDefenseProfile removes a Saas Bot Defense profile. +func (b *BigIP) DeleteSaasBotDefenseProfile(name string) error { + return b.delete(uriSaas, uriSaasBotDefense, uriProfile, name) +} + +// ModifySaasBotDefenseProfile allows you to change any attribute of a Saas Bot Defense profile. +// Fields that can be modified are referenced in the SaasBotDefense struct. +func (b *BigIP) ModifySaasBotDefenseProfile(name string, config *SaasBotDefenseProfile) error { + return b.patch(config, uriSaas, uriSaasBotDefense, uriProfile, name) +} + +func (b *BigIP) GetSaasBotDefenseProfile(name string) (*SaasBotDefenseProfile, error) { + var saasBotDefense SaasBotDefenseProfile + err, ok := b.getForEntity(&saasBotDefense, uriSaas, uriSaasBotDefense, uriProfile, name) + if err != nil { + return nil, err + } + if !ok { + return nil, nil + } + return &saasBotDefense, nil +} From 257a84c50d9faf9dc4c5804bfc7fab5f68883c47 Mon Sep 17 00:00:00 2001 From: RavinderReddyF5 Date: Thu, 12 Dec 2024 08:10:58 +0530 Subject: [PATCH 4/4] adding bot-defense profile --- bigip/resource_bigip_saas_bot_defense.go | 80 ++++++++++++++----- .../bigip_saas_bot_defence_profile.md | 74 +++++++++++++++++ .../github.com/f5devcentral/go-bigip/ltm.go | 13 +-- 3 files changed, 141 insertions(+), 26 deletions(-) create mode 100644 docs/resources/bigip_saas_bot_defence_profile.md diff --git a/bigip/resource_bigip_saas_bot_defense.go b/bigip/resource_bigip_saas_bot_defense.go index adb659bc..1c6c0ee4 100644 --- a/bigip/resource_bigip_saas_bot_defense.go +++ b/bigip/resource_bigip_saas_bot_defense.go @@ -28,73 +28,89 @@ func resourceBigipSaasBotDefenseProfile() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, - Description: "Unique name for the Bot Defense profile", + Description: "Unique name for the Distributed Cloud Services Bot Defense profile", ValidateFunc: validateF5NameWithDirectory, }, "defaults_from": { Type: schema.TypeString, Optional: true, Default: "/Common/bd", - Description: "Specifies the profile from which this profile inherits settings. The default is the system-supplied `bd` profile", + Description: "Distributed Cloud Services Bot Defense parent profile from which this profile will inherit settings.", ValidateFunc: validateF5Name, }, "description": { Type: schema.TypeString, Optional: true, Computed: true, - Description: "User defined description for Bot Defense profile", + Description: "Specifies descriptive text that identifies the BD profile.", }, "application_id": { Type: schema.TypeString, Required: true, - Description: "User defined description for Bot Defense profile", + Sensitive: true, + Description: "Specifies the Bot Defense API application ID, enter the value provided by F5 Support", }, "tenant_id": { Type: schema.TypeString, Required: true, - Description: "User defined description for Bot Defense profile", + Description: "Specifies the tenant ID, enter the value provided by F5 Support", }, "api_key": { Type: schema.TypeString, Required: true, Sensitive: true, - Description: "User defined description for Bot Defense profile", + Description: "Specifies the API key, enter the value provided by F5 Support.", }, "shape_protection_pool": { Type: schema.TypeString, Required: true, - Description: "User defined description for Bot Defense profile", + Description: "Specifies the web hostname to which API requests are made", }, "ssl_profile": { Type: schema.TypeString, Required: true, - Description: "User defined description for Bot Defense profile", + Description: "Specifies a server-side SSL profile that is different from what the application pool uses", }, "protected_endpoints": { Type: schema.TypeList, Required: true, - Description: "User defined description for Bot Defense profile", + Description: "Use these settings to configure which pages on the website will be protected by BD", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, Required: true, - Description: "User defined description for Bot Defense profile", + Description: "Unique name for the protected endpoint", }, "host": { Type: schema.TypeString, - Required: true, - Description: "User defined description for Bot Defense profile", + Optional: true, + Computed: true, + Description: "hostname or IP address of the web page to be protected by the Bot Defense", }, "endpoint": { Type: schema.TypeString, - Required: true, - Description: "User defined description for Bot Defense profile", + Optional: true, + Computed: true, + Description: "Specifies the path to the web page to be protected by BD. For example, `/login`.", + }, + "mitigation_action": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "Specifies whether the BIG-IP or F5 XC Bot Defense handles mitigation of malicious HTTP requests. This field is enabled only if the Service Level field is set to Advanced/Premium", }, "post": { Type: schema.TypeString, - Required: true, - Description: "User defined description for Bot Defense profile", + Optional: true, + Computed: true, + Description: "POST field to protect the path when it has a POST method, `enabled` or `disabled`", + }, + "put": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "PUT field to protect the path when it has a PUT method,`enabled` or `disabled`", }, }, }, @@ -129,10 +145,15 @@ func resourceBigipSaasBotDefenseProfileRead(ctx context.Context, d *schema.Resou if err != nil { return diag.FromErr(err) } - log.Printf("[DEBUG] Bot Defense Profile config :%+v ", botProfile) + log.Printf("[DEBUG] Defense Profile Resp :%+v ", botProfile) d.Set("name", botProfile.FullPath) d.Set("defaults_from", botProfile.DefaultsFrom) d.Set("description", botProfile.Description) + d.Set("tenant_id", botProfile.TenantId) + d.Set("api_key", botProfile.ApiKey) + d.Set("shape_protection_pool", botProfile.ShapeProtectionPool) + d.Set("ssl_profile", botProfile.SslProfile) + d.Set("protected_endpoints", flattenProtectedEndpointsReference(botProfile.ProtectedEndpointsReference.Items)) return nil } @@ -178,10 +199,12 @@ func getSaasBotDefenseProfileConfig(d *schema.ResourceData, config *bigip.SaasBo for _, endpoint := range d.Get("protected_endpoints").([]interface{}) { ep := endpoint.(map[string]interface{}) protectEndpoint = append(protectEndpoint, bigip.ProtectedEndpoint{ - Name: ep["name"].(string), - Host: ep["host"].(string), - Endpoint: ep["endpoint"].(string), - Post: ep["post"].(string), + Name: ep["name"].(string), + Host: ep["host"].(string), + Endpoint: ep["endpoint"].(string), + Post: ep["post"].(string), + Put: ep["put"].(string), + MitigationAction: ep["mitigation_action"].(string), }) } config.ProtectedEndpointsReference.Items = protectEndpoint @@ -189,6 +212,21 @@ func getSaasBotDefenseProfileConfig(d *schema.ResourceData, config *bigip.SaasBo return config } +func flattenProtectedEndpointsReference(data interface{}) []interface{} { + var prtctEndpt []interface{} + for _, ep := range data.([]bigip.ProtectedEndpoint) { + prtctEndpt = append(prtctEndpt, map[string]interface{}{ + "name": ep.Name, + "host": ep.Host, + "endpoint": ep.Endpoint, + "post": ep.Post, + "put": ep.Put, + "mitigation_action": ep.MitigationAction, + }) + } + return prtctEndpt +} + // { // "name": "/Common/bd-test", // "applicationId": "89fb0bfcb4bf4c578fad9adb37ce3b19", diff --git a/docs/resources/bigip_saas_bot_defence_profile.md b/docs/resources/bigip_saas_bot_defence_profile.md new file mode 100644 index 00000000..6b3a65f1 --- /dev/null +++ b/docs/resources/bigip_saas_bot_defence_profile.md @@ -0,0 +1,74 @@ +--- +layout: "bigip" +page_title: "BIG-IP: bigip_saas_bot_defense_profile" +subcategory: "Distributed Cloud Services" +description: |- + Provides details about bigip_saas_bot_defense_profile resource +--- + +# bigip\_saas\_bot\_defense\_profile + +`bigip_saas_bot_defense_profile` Resource used for Configures Distributed Cloud Services Bot Defense profile, for more info [Bot defence](https://techdocs.f5.com/en-us/bigip-17-1-0/big-ip-saas-bot-defense.html) + +## Example Usage + +```hcl +resource "bigip_saas_bot_defense_profile" "test-bot-defense" { + name = "/Common/test-saas-bot-defense" + application_id = "89fb0bfcb4bxxxxx8fad9adb37ce3b19" + tenant_id = "a-aaxxxxxvaYOV" + api_key = "49840d1dd6faxxxxxxc88762eb398eee" + shape_protection_pool = "/Common/cs1.pool" + ssl_profile = "/Common/cloud-service-default-ssl" + protected_endpoints { + name = "pe1" + host = "abc.com" + endpoint = "/login" + post = "enabled" + } +} +``` +## Argument Reference + +* `name` (Required,type `string`) Unique name for the Distributed Cloud Services Bot Defense profile. Full path is the combination of the `partition + profile name`,For example `/Common/test-bot-tc1`. + +* `defaults_from` - (optional,type `string`) Distributed Cloud Services Bot Defense parent profile from which this profile will inherit settings. The default is the system-supplied `bd` profile. + +* `description` - (optional,type `string`) Specifies descriptive text that identifies the BD profile. + +* `application_id` - (Required,type `string`) Specifies the Bot Defense API application ID, enter the value provided by F5 Support + +* `api_key` - (Required,type `string`) Specifies the API key, enter the value provided by F5 Support. + +* `tenant_id` - (Required,type `string`) Specifies the tenant ID, enter the value provided by F5 Support. + +* `shape_protection_pool` - (Required,type `string`) Specifies the web hostname to which API requests are made. + +* `ssl_profile` - (Required,type `string`) Specifies a server-side SSL profile that is different from what the application pool uses. + + +* `protected_endpoints` - (Required,`list`) Use these settings to configure which pages on the website will be protected by BD. +It is block `protected_endpoints` block takes input for the protected endpoints. See [protected endpoints](#protected-endpoints) below for more details. + +### protected endpoints + +This block supports the following arguments: + +* `name` - (Required,`string`) Unique name for the protected endpoint. + +* `host` - (Optional,`string`) hostname or IP address of the web page to be protected by the Bot Defense. + +* `endpoint` - (Optional,`string`) Specifies the path to the web page to be protected by BD. For example, `/login`. + +* `mitigation_action` - (Optional,`string`) Specifies whether the BIG-IP or F5 XC Bot Defense handles mitigation of malicious HTTP requests. This field is enabled only if the Service Level field is set to Advanced/Premium. + +* `post` - (Optional,`string`) POST field to protect the path when it has a POST method, `enabled` or `disabled`. + +* `put` - (Optional,`string`) PUT field to protect the path when it has a PUT method,`enabled` or `disabled`. + +## Import + +BIG-IP Distributed Cloud Services Bot Defense profile can be imported using the `//`, e.g. +```bash +terraform import bigip_saas_bot_defense_profile.test-bot /Common/testbotprofile01 +``` diff --git a/vendor/github.com/f5devcentral/go-bigip/ltm.go b/vendor/github.com/f5devcentral/go-bigip/ltm.go index 8e1f690e..2ce24aed 100644 --- a/vendor/github.com/f5devcentral/go-bigip/ltm.go +++ b/vendor/github.com/f5devcentral/go-bigip/ltm.go @@ -4414,10 +4414,13 @@ type SaasBotDefenseProfile struct { // } type ProtectedEndpoint struct { - Name string `json:"name,omitempty"` - Host string `json:"host,omitempty"` - Endpoint string `json:"endpoint,omitempty"` - Post string `json:"post,omitempty"` + Name string `json:"name,omitempty"` + Host string `json:"host,omitempty"` + Endpoint string `json:"endpoint,omitempty"` + Post string `json:"post,omitempty"` + Put string `json:"put,omitempty"` + AnyMethod string `json:"anyMethod,omitempty"` + MitigationAction string `json:"mitigationAction,omitempty"` } // AddSaasBotDefenseProfile creates a new Saas Bot Defense profile on the BIG-IP system. @@ -4438,7 +4441,7 @@ func (b *BigIP) ModifySaasBotDefenseProfile(name string, config *SaasBotDefenseP func (b *BigIP) GetSaasBotDefenseProfile(name string) (*SaasBotDefenseProfile, error) { var saasBotDefense SaasBotDefenseProfile - err, ok := b.getForEntity(&saasBotDefense, uriSaas, uriSaasBotDefense, uriProfile, name) + err, ok := b.getForEntity(&saasBotDefense, uriSaas, uriSaasBotDefense, uriProfile, name, "?expandSubcollections=true") if err != nil { return nil, err }