Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resource/cloudflare_api_shield_operation_schema_validation_settings #2852

Merged
merged 2 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/2852.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
cloudflare_api_shield_operation_schema_validation_settings
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
page_title: "cloudflare_api_shield_operation_schema_validation_settings Resource - Cloudflare"
subcategory: ""
description: |-
Provides a resource to manage operation-level settings in API Shield Schema Validation 2.0.
---

# cloudflare_api_shield_operation_schema_validation_settings (Resource)

Provides a resource to manage operation-level settings in API Shield Schema Validation 2.0.

## Example Usage

```terraform
resource "cloudflare_api_shield_operation" "example" {
zone_id = "0da42c8d2132a9ddaf714f9e7c920711"
method = "GET"
host = "api.example.com"
endpoint = "/path"
}

resource "cloudflare_api_shield_operation_schema_validation_settings" "example" {
zone_id = "0da42c8d2132a9ddaf714f9e7c920711"
operation_id = cloudflare_api_shield_operation.example.id
mitigation_action = "block"
}
```
<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `operation_id` (String) Operation ID these settings should apply to. **Modifying this attribute will force creation of a new resource.**
- `zone_id` (String) The zone identifier to target for the resource. **Modifying this attribute will force creation of a new resource.**

### Optional

- `mitigation_action` (String) The mitigation action to apply to this operation.

### Read-Only

- `id` (String) The ID of this resource.


Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
resource "cloudflare_api_shield_operation" "example" {
zone_id = "0da42c8d2132a9ddaf714f9e7c920711"
method = "GET"
host = "api.example.com"
endpoint = "/path"
}

resource "cloudflare_api_shield_operation_schema_validation_settings" "example" {
zone_id = "0da42c8d2132a9ddaf714f9e7c920711"
operation_id = cloudflare_api_shield_operation.example.id
mitigation_action = "block"
}
217 changes: 109 additions & 108 deletions internal/sdkv2provider/provider.go

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package sdkv2provider

import (
"context"
"fmt"

"github.com/pkg/errors"

"github.com/MakeNowJust/heredoc/v2"
"github.com/cloudflare/cloudflare-go"
"github.com/cloudflare/terraform-provider-cloudflare/internal/consts"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func resourceCloudflareAPIShieldOperationSchemaValidationSettings() *schema.Resource {
return &schema.Resource{
Schema: resourceCloudflareAPIShieldOperationSchemaValidationSettingsSchema(),
CreateContext: resourceCloudflareAPIShieldOperationSchemaValidationSettingsCreate,
ReadContext: resourceCloudflareAPIShieldOperationSchemaValidationSettingsRead,
UpdateContext: resourceCloudflareAPIShieldOperationSchemaValidationSettingsUpdate,
DeleteContext: resourceCloudflareAPIShieldOperationSchemaValidationSettingsDelete,
Importer: &schema.ResourceImporter{
StateContext: nil,
},
Description: heredoc.Doc(`
Provides a resource to manage operation-level settings in API Shield Schema Validation 2.0.
`),
}
}

func resourceCloudflareAPIShieldOperationSchemaValidationSettingsCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
return resourceCloudflareAPIShieldOperationSchemaValidationSettingsUpdate(ctx, d, meta)
}

func resourceCloudflareAPIShieldOperationSchemaValidationSettingsUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*cloudflare.API)
zoneID := d.Get(consts.ZoneIDSchemaKey).(string)

operationID := d.Get("operation_id").(string)

var mitigationAction *string
if ma, ok := d.GetOk("mitigation_action"); ok {
mitigationAction = cloudflare.StringPtr(ma.(string))
}

_, err := client.UpdateAPIShieldOperationSchemaValidationSettings(
ctx,
cloudflare.ZoneIdentifier(zoneID),
cloudflare.UpdateAPIShieldOperationSchemaValidationSettings{
operationID: cloudflare.APIShieldOperationSchemaValidationSettings{
MitigationAction: mitigationAction,
},
},
)

if err != nil {
return diag.FromErr(errors.Wrap(err, "failed to create API Shield Operation Schema Validation Settings"))
}

// Settings are configured at the operation level so using the operationID as the ID
d.SetId(operationID)
return resourceCloudflareAPIShieldOperationSchemaValidationSettingsRead(ctx, d, meta)
}

func resourceCloudflareAPIShieldOperationSchemaValidationSettingsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*cloudflare.API)
zoneID := d.Get(consts.ZoneIDSchemaKey).(string)

operationID := d.Get("operation_id").(string)
settings, err := client.GetAPIShieldOperationSchemaValidationSettings(
ctx,
cloudflare.ZoneIdentifier(zoneID),
cloudflare.GetAPIShieldOperationSchemaValidationSettingsParams{
OperationID: operationID,
},
)

if err != nil {
return diag.FromErr(fmt.Errorf("failed to fetch API Shield Operation Schema Validation Settings: %w", err))
}

if err := d.Set("mitigation_action", settings.MitigationAction); err != nil {
return diag.FromErr(err)
}

// Settings are configured at the operation level so using the zoneID as the ID
d.SetId(operationID)
return nil
}

func resourceCloudflareAPIShieldOperationSchemaValidationSettingsDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*cloudflare.API)
zoneID := d.Get(consts.ZoneIDSchemaKey).(string)
operationID := d.Get("operation_id").(string)

// There is no DELETE endpoint for schema validation settings,
// so terraform should reset the state to default settings
_, err := client.UpdateAPIShieldOperationSchemaValidationSettings(
ctx,
cloudflare.ZoneIdentifier(zoneID),
cloudflare.UpdateAPIShieldOperationSchemaValidationSettings{
operationID: cloudflare.APIShieldOperationSchemaValidationSettings{},
},
)
if err != nil {
return diag.FromErr(fmt.Errorf("failed to delete API Shield Operation Schema Validation Settings: %w", err))
}

return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package sdkv2provider

import (
"fmt"
"os"
"testing"

"github.com/cloudflare/terraform-provider-cloudflare/internal/consts"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

func TestAccCloudflareAPIShieldOperationSchemaValidationSettings_Create(t *testing.T) {
// Temporarily unset CLOUDFLARE_API_TOKEN if it is set as the API token
// endpoint does not yet support the API tokens without an explicit scope.
if os.Getenv("CLOUDFLARE_API_TOKEN") != "" {
t.Setenv("CLOUDFLARE_API_TOKEN", "")
}

rnd := generateRandomResourceName()
resourceID := "cloudflare_api_shield_operation_schema_validation_settings." + rnd
zoneID := os.Getenv("CLOUDFLARE_ZONE_ID")

block := "block"
none := "none"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: testAccCloudflareAPIShieldOperationSchemaValidationSettingsMitigation(rnd, zoneID, &block),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceID, consts.ZoneIDSchemaKey, zoneID),
resource.TestCheckResourceAttr(resourceID, "mitigation_action", "block"),
),
},
{
Config: testAccCloudflareAPIShieldOperationSchemaValidationSettingsMitigation(rnd, zoneID, nil),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceID, consts.ZoneIDSchemaKey, zoneID),
resource.TestCheckResourceAttr(resourceID, "mitigation_action", ""),
),
},
{
Config: testAccCloudflareAPIShieldOperationSchemaValidationSettingsMitigation(rnd, zoneID, &none),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceID, consts.ZoneIDSchemaKey, zoneID),
resource.TestCheckResourceAttr(resourceID, "mitigation_action", "none"),
),
},
{
Config: testAccCloudflareAPIShieldOperationSchemaValidationSettingsNoMitigation(rnd, zoneID),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceID, consts.ZoneIDSchemaKey, zoneID),
resource.TestCheckResourceAttr(resourceID, "mitigation_action", ""),
),
},
},
})
}

func testAccCloudflareAPIShieldOperationSchemaValidationSettingsMitigation(resourceName, zone string, mitigation *string) string {
action := "null"
if mitigation != nil {
action = fmt.Sprintf("\"%s\"", *mitigation)
}

return fmt.Sprintf(`
resource "cloudflare_api_shield_operation" "terraform_test_acc_operation" {
zone_id = "%[2]s"
host = "foo.com"
method = "GET"
endpoint = "/api"
}
resource "cloudflare_api_shield_operation_schema_validation_settings" "%[1]s" {
zone_id = "%[2]s"
operation_id = cloudflare_api_shield_operation.terraform_test_acc_operation.id
mitigation_action = %[3]s
}
`, resourceName, zone, action)
}

func testAccCloudflareAPIShieldOperationSchemaValidationSettingsNoMitigation(resourceName, zone string) string {
return fmt.Sprintf(`
resource "cloudflare_api_shield_operation" "terraform_test_acc_operation" {
zone_id = "%[2]s"
host = "foo.com"
method = "GET"
endpoint = "/api"
}
resource "cloudflare_api_shield_operation_schema_validation_settings" "%[1]s" {
zone_id = "%[2]s"
operation_id = cloudflare_api_shield_operation.terraform_test_acc_operation.id
}
`, resourceName, zone)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package sdkv2provider

import (
"github.com/cloudflare/terraform-provider-cloudflare/internal/consts"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func resourceCloudflareAPIShieldOperationSchemaValidationSettingsSchema() map[string]*schema.Schema {
return map[string]*schema.Schema{
consts.ZoneIDSchemaKey: {
Description: consts.ZoneIDSchemaDescription,
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"operation_id": {
Description: "Operation ID these settings should apply to",
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"mitigation_action": {
Description: "The mitigation action to apply to this operation",
Type: schema.TypeString,
Optional: true,
},
}
}
Loading