Skip to content
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
30 changes: 25 additions & 5 deletions internal/provider/owasp_custom_data_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ func (r *OwaspCustomDataResource) Schema(ctx context.Context, req resource.Schem
"data": schema.StringAttribute{
MarkdownDescription: "The content of the custom data.",
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
},
},
}
Expand Down Expand Up @@ -115,7 +112,7 @@ func (r *OwaspCustomDataResource) Create(ctx context.Context, req resource.Creat
data.Filename = types.StringValue(data.Filename.ValueString())
data.Data = types.StringValue(data.Data.ValueString())

tflog.Trace(ctx, "created a resource owasp custom rule")
tflog.Trace(ctx, "created a resource owasp custom data")

resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}
Expand Down Expand Up @@ -163,7 +160,30 @@ func (r *OwaspCustomDataResource) Update(ctx context.Context, req resource.Updat
var data OwaspCustomDataResourceModel

resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
resp.Diagnostics.AddError("Client Error", "Unable to update owasp custom data, got error")

tflog.Debug(ctx, "updating the resource")

// Decoding shenanigans
content := base64.StdEncoding.EncodeToString([]byte(r.getMarker() + data.Data.ValueString()))

operation := ClientBackoff(func() (*api.LoadMasterResponse, error) {
return r.client.AddOwaspCustomData(data.Filename.ValueString(), content)
})
response, err := backoff.Retry(ctx, operation, backoff.WithBackOff(backoff.NewExponentialBackOff()))

if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update owasp custom data, got error: %s", err))
return
}
tflog.SetField(ctx, "response", response)
tflog.Trace(ctx, "Received valid response from API")

data.Filename = types.StringValue(data.Filename.ValueString())
data.Data = types.StringValue(data.Data.ValueString())

tflog.Trace(ctx, "updated a resource owasp custom data")

resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

func (r *OwaspCustomDataResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
Expand Down
50 changes: 50 additions & 0 deletions internal/provider/owasp_custom_data_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package provider

import (
"fmt"
"os"
"path/filepath"
"regexp"
Expand Down Expand Up @@ -151,6 +152,46 @@ func TestOwaspCustomDataResourceReal1(t *testing.T) {
})
}

func TestOwaspCustomDataResourceUpdate(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Create and Read testing
{
Config: testOwaspCustomDataResourceUpdate("1"),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(
"loadmaster_owasp_custom_data.test_data",
tfjsonpath.New("filename"),
knownvalue.StringExact("test_rule_replace_url.txt"),
),
statecheck.ExpectKnownValue(
"loadmaster_owasp_custom_data.test_data",
tfjsonpath.New("data"),
knownvalue.StringExact("Data1"),
),
},
},
{
Config: testOwaspCustomDataResourceUpdate("2"),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(
"loadmaster_owasp_custom_data.test_data",
tfjsonpath.New("filename"),
knownvalue.StringExact("test_rule_replace_url.txt"),
),
statecheck.ExpectKnownValue(
"loadmaster_owasp_custom_data.test_data",
tfjsonpath.New("data"),
knownvalue.StringExact("Data2"),
),
},
},
},
})
}

func testOwaspCustomDataResource() string {
return `
resource "loadmaster_owasp_custom_data" "test_data" {
Expand All @@ -160,6 +201,15 @@ resource "loadmaster_owasp_custom_data" "test_data" {
`
}

func testOwaspCustomDataResourceUpdate(version string) string {
return fmt.Sprintf(`
resource "loadmaster_owasp_custom_data" "test_data" {
filename = "test_rule_replace_url.txt"
data = "Data%s"
}
`, version)
}

func testOwaspCustomDataResourceReal1() string {
return `
resource "loadmaster_owasp_custom_data" "test_data" {
Expand Down
26 changes: 22 additions & 4 deletions internal/provider/owasp_custom_rule_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ func (r *OwaspCustomRuleResource) Schema(ctx context.Context, req resource.Schem
"data": schema.StringAttribute{
MarkdownDescription: "The content of the custom rule.",
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
},
},
}
Expand Down Expand Up @@ -164,8 +161,29 @@ func (r *OwaspCustomRuleResource) Update(ctx context.Context, req resource.Updat
var data OwaspCustomRuleResourceModel

resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
resp.Diagnostics.AddError("Client Error", "Unable to update owasp custom rule, got error")

tflog.Debug(ctx, "updating the resource")

content := base64.StdEncoding.EncodeToString([]byte(r.getMarker() + data.Data.ValueString()))

operation := ClientBackoff(func() (*api.LoadMasterResponse, error) {
return r.client.AddOwaspCustomRule(data.Filename.ValueString(), content)
})
response, err := backoff.Retry(ctx, operation, backoff.WithBackOff(backoff.NewExponentialBackOff()))

if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to update owasp custom rule, got error: %s", err))
return
}
tflog.SetField(ctx, "response", response)
tflog.Trace(ctx, "Received valid response from API")

data.Filename = types.StringValue(data.Filename.ValueString())
data.Data = types.StringValue(data.Data.ValueString())

tflog.Trace(ctx, "updated a resource owasp custom rule")

resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

func (r *OwaspCustomRuleResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
Expand Down
60 changes: 59 additions & 1 deletion internal/provider/owasp_custom_rule_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package provider

import (
"fmt"
"os"
"path/filepath"
"regexp"
Expand Down Expand Up @@ -65,6 +66,46 @@ func TestOwaspCustomRuleResource(t *testing.T) {
})
}

func TestOwaspCustomRuleResourceUpdate(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Create and Read testing
{
Config: testOwaspCustomRuleResourceUpdate("1"),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(
"loadmaster_owasp_custom_rule.test_rule",
tfjsonpath.New("filename"),
knownvalue.StringExact("test_rule_replace_url.conf"),
),
statecheck.ExpectKnownValue(
"loadmaster_owasp_custom_rule.test_rule",
tfjsonpath.New("data"),
knownvalue.StringRegexp(regexp.MustCompile(`.*SecMarker BEGIN_ALLOWLIST_login.*`)),
),
},
},
{
Config: testOwaspCustomRuleResourceUpdate("2"),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(
"loadmaster_owasp_custom_rule.test_rule",
tfjsonpath.New("filename"),
knownvalue.StringExact("test_rule_replace_url.conf"),
),
statecheck.ExpectKnownValue(
"loadmaster_owasp_custom_rule.test_rule",
tfjsonpath.New("data"),
knownvalue.StringRegexp(regexp.MustCompile(`.*SecMarker BEGIN_ALLOWLIST_login.*`)),
),
},
},
},
})
}

func TestOwaspCustomRuleResourceDeletedByRemote(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand Down Expand Up @@ -249,6 +290,24 @@ EOT
`
}

func testOwaspCustomRuleResourceUpdate(version string) string {
return fmt.Sprintf(`
resource "loadmaster_owasp_custom_rule" "test_rule" {
filename = "test_rule_replace_url.conf"
data = <<EOT
SecMarker BEGIN_ALLOWLIST_login

# START allowlisting block for URI /login SecRule REQUEST_URI "!@beginsWith /login%s" \
"id:11001,phase:1,pass,t:lowercase,nolog,skipAfter:END_ALLOWLIST_login"
SecRule REQUEST_URI "!@beginsWith /login%s" \
"id:11002,phase:2,pass,t:lowercase,nolog,skipAfter:END_ALLOWLIST_login"

SecMarker END_ALLOWLIST_login
EOT
}
`, version, version)
}

func testRealOwaspCustomRuleWithData1() string {
return `

Expand Down Expand Up @@ -319,6 +378,5 @@ EOT

depends_on = [loadmaster_owasp_custom_data.data]
}

`
}