From d166ce2100ce50935a5d3e084e4e78d9af7b7f92 Mon Sep 17 00:00:00 2001 From: Konstantin Nechaev Date: Fri, 29 Nov 2024 14:37:08 +0200 Subject: [PATCH] set_response_header rewritten to work the same way as api --- docs/resources/rule_set_response_header.md | 17 ++- wallarm/resource_rule_set_response_header.go | 145 ++++++++----------- wallarm/utils.go | 10 ++ 3 files changed, 78 insertions(+), 94 deletions(-) diff --git a/docs/resources/rule_set_response_header.md b/docs/resources/rule_set_response_header.md index ca3c946..a8de827 100644 --- a/docs/resources/rule_set_response_header.md +++ b/docs/resources/rule_set_response_header.md @@ -17,21 +17,22 @@ This is because Terraform is designed to keep its configurations stable and not ```hcl # Append the "Server" header with the "Wallarm solution" value -# and the "Blocked" header with the "Blocked by Wallarm" value +# and the "Server" header with the "Blocked by Wallarm" value # to the requests sent to the application with ID 3 resource "wallarm_rule_set_response_header" "resp_headers" { mode = "append" + name = "Server" action { point = { instance = 3 } } - - headers = { - Server = "Wallarm solution" - Blocked = "Blocked by Wallarm" + + values = { + "Wallarm solution" + "Blocked by Wallarm" } } @@ -43,9 +44,10 @@ resource "wallarm_rule_set_response_header" "resp_headers" { resource "wallarm_rule_set_response_header" "delete_header" { mode = "replace" + name = "Wallarm component" headers = { - Wallarm component = " " + " " } } @@ -54,7 +56,8 @@ resource "wallarm_rule_set_response_header" "delete_header" { ## Argument Reference * `mode` - (**required**) mode of header processing. Valid options: `append`, `replace` -* `headers` - (**required**) the associative array of key/value headers. Might be defined as much headers as need at once. +* `name` - (**required**) description. +* `values` - (**required**) array of headers. Might be defined as much headers as need at once. * `action` - (optional) a series of conditions, see below for a a full list . diff --git a/wallarm/resource_rule_set_response_header.go b/wallarm/resource_rule_set_response_header.go index 59df5db..f9b8152 100644 --- a/wallarm/resource_rule_set_response_header.go +++ b/wallarm/resource_rule_set_response_header.go @@ -26,7 +26,7 @@ func resourceWallarmSetResponseHeader() *schema.Resource { Schema: map[string]*schema.Schema{ "rule_id": { - Type: schema.TypeList, + Type: schema.TypeInt, Computed: true, Elem: &schema.Schema{Type: schema.TypeInt}, }, @@ -67,8 +67,13 @@ func resourceWallarmSetResponseHeader() *schema.Resource { ValidateFunc: validation.StringInSlice([]string{"append", "replace"}, false), }, - "headers": { - Type: schema.TypeMap, + "name": { + Type: schema.TypeString, + Optional: true, + }, + + "values": { + Type: schema.TypeList, Required: true, Elem: &schema.Schema{Type: schema.TypeString}, }, @@ -191,7 +196,8 @@ func resourceWallarmSetResponseHeaderCreate(d *schema.ResourceData, m interface{ clientID := retrieveClientID(d, client) comment := d.Get("comment").(string) mode := d.Get("mode").(string) - headers := d.Get("headers").(map[string]interface{}) + name := d.Get("name").(string) + values := d.Get("values").([]string) actionsFromState := d.Get("action").(*schema.Set) action, err := expandSetToActionDetailsList(actionsFromState) @@ -199,35 +205,25 @@ func resourceWallarmSetResponseHeaderCreate(d *schema.ResourceData, m interface{ return err } - var ruleIDs []int - for k, v := range headers { - vp := &wallarm.ActionCreate{ - Type: "set_response_header", - Clientid: clientID, - Action: &action, - Mode: mode, - Name: k, - Values: []string{v.(string)}, - Validated: false, - Comment: comment, - VariativityDisabled: true, - } - actionResp, err := client.HintCreate(vp) - if err != nil { - return err - } - - actionID := actionResp.Body.ActionID - d.Set("action_id", actionID) - - ruleIDs = append(ruleIDs, actionResp.Body.ID) - - resID := fmt.Sprintf("%d/%d/%d", clientID, actionID, actionResp.Body.ID) - d.SetId(resID) + vp := &wallarm.ActionCreate{ + Type: "set_response_header", + Clientid: clientID, + Action: &action, + Mode: mode, + Name: name, + Values: values, + Validated: false, + Comment: comment, + VariativityDisabled: true, + } + actionResp, err := client.HintCreate(vp) + if err != nil { + return err } - d.Set("rule_id", ruleIDs) + d.Set("action_id", actionResp.Body.ActionID) + d.Set("rule_id", actionResp.Body.ID) d.Set("client_id", clientID) return nil @@ -236,10 +232,11 @@ func resourceWallarmSetResponseHeaderCreate(d *schema.ResourceData, m interface{ func resourceWallarmSetResponseHeaderRead(d *schema.ResourceData, m interface{}) error { client := m.(wallarm.API) clientID := retrieveClientID(d, client) + ruleID := d.Get("rule_id").(int) actionID := d.Get("action_id").(int) mode := d.Get("mode").(string) - ruleID := d.Get("rule_id").(int) - headers := d.Get("headers").(map[string]interface{}) + name := d.Get("name").(string) + values := d.Get("values").([]string) actionsFromState := d.Get("action").(*schema.Set) action, err := expandSetToActionDetailsList(actionsFromState) @@ -247,14 +244,6 @@ func resourceWallarmSetResponseHeaderRead(d *schema.ResourceData, m interface{}) return err } - var ruleIDInterface []interface{} - if v, ok := d.GetOk("rule_id"); ok { - ruleIDInterface = v.([]interface{}) - } else { - return nil - } - ruleIDs := expandInterfaceToIntList(ruleIDInterface) - hint := &wallarm.HintRead{ Limit: 1000, Offset: 0, @@ -263,6 +252,7 @@ func resourceWallarmSetResponseHeaderRead(d *schema.ResourceData, m interface{}) Filter: &wallarm.HintFilter{ Clientid: []int{clientID}, ID: []int{ruleID}, + Type: []string{"set_response_header"}, }, } actionHints, err := client.HintRead(hint) @@ -274,52 +264,42 @@ func resourceWallarmSetResponseHeaderRead(d *schema.ResourceData, m interface{}) // Assign new values to the old struct slice. fillInDefaultValues(&action) + expectedRule := wallarm.ActionBody{ + ActionID: actionID, + Type: "set_response_header", + Mode: mode, + Name: name, + Values: stringSliceToInterfaceSlice(values), + } + var notFoundRules []int - var updatedRuleIDs []int + var updatedRuleID int for _, rule := range *actionHints.Body { - - // Check out by ID. The specific rule should be found. - if wallarm.Contains(ruleIDs, rule.ID) { - updatedRuleIDs = append(updatedRuleIDs, rule.ID) + if ruleID == rule.ID { + updatedRuleID = rule.ID continue } - for name, value := range headers { - - expectedRule := wallarm.ActionBody{ - ActionID: actionID, - Type: "set_response_header", - Action: action, - Mode: mode, - Name: name, - Values: []interface{}{value}, - } - - actualRule := &wallarm.ActionBody{ - ActionID: rule.ActionID, - Type: rule.Type, - Action: rule.Action, - Mode: rule.Mode, - Name: rule.Name, - Values: rule.Values, - } + actualRule := &wallarm.ActionBody{ + ActionID: rule.ActionID, + Type: rule.Type, + } - if cmp.Equal(expectedRule, *actualRule) && equalWithoutOrder(action, rule.Action) { - updatedRuleIDs = append(updatedRuleIDs, rule.ID) - continue - } + if cmp.Equal(expectedRule, *actualRule) && equalWithoutOrder(action, rule.Action) { + updatedRuleID = rule.ID + continue } notFoundRules = append(notFoundRules, rule.ID) } - if err := d.Set("rule_id", updatedRuleIDs); err != nil { + if err := d.Set("rule_id", updatedRuleID); err != nil { return err } d.Set("client_id", clientID) - if len(updatedRuleIDs) == 0 { + if updatedRuleID == 0 { log.Printf("[WARN] these rule IDs: %v have been found under the action ID: %d. But it isn't in the Terraform Plan.", notFoundRules, actionID) d.SetId("") } @@ -330,26 +310,17 @@ func resourceWallarmSetResponseHeaderRead(d *schema.ResourceData, m interface{}) func resourceWallarmSetResponseHeaderDelete(d *schema.ResourceData, m interface{}) error { client := m.(wallarm.API) clientID := retrieveClientID(d, client) + ruleID := d.Get("rule_id").(int) - var ruleIDInterface []interface{} - if v, ok := d.GetOk("rule_id"); ok { - ruleIDInterface = v.([]interface{}) - } else { - return nil + h := &wallarm.HintDelete{ + Filter: &wallarm.HintDeleteFilter{ + Clientid: []int{clientID}, + ID: ruleID, + }, } - ruleIDs := expandInterfaceToIntList(ruleIDInterface) - - for _, ruleID := range ruleIDs { - h := &wallarm.HintDelete{ - Filter: &wallarm.HintDeleteFilter{ - Clientid: []int{clientID}, - ID: ruleID, - }, - } - if err := client.HintDelete(h); err != nil { - return err - } + if err := client.HintDelete(h); err != nil { + return err } return nil diff --git a/wallarm/utils.go b/wallarm/utils.go index 0ffa816..1e3177e 100644 --- a/wallarm/utils.go +++ b/wallarm/utils.go @@ -536,6 +536,16 @@ func equalWithoutOrder(conditions_a, conditions_b []wallarm.ActionDetails) bool return true } +func stringSliceToInterfaceSlice(strings []string) []interface{} { + var result []interface{} + + for _, str := range strings { + result = append(result, str) + } + + return result +} + // compare for action condition func compareActionDetails(condition1, condition2 wallarm.ActionDetails) bool { return condition1.Type == condition2.Type &&