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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 2.5.1

BUG FIXES:

- Honor `read_response_codes` during Read drift detection so unexpected read HTTP status codes are treated as drift.
- Avoid false post-creation drift when the prior sanitized response is null.
- Refactor `responseCodeChecker` for simpler call sites across resource, action, and tests. Based on #149 by @JackSlateur.

## 2.5.0

FEATURES:
Expand Down
10 changes: 1 addition & 9 deletions internal/provider/curl_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"io"
"net/http"
"strconv"
"time"

"github.com/hashicorp/terraform-plugin-framework-validators/actionvalidator"
Expand Down Expand Up @@ -192,13 +191,6 @@ func (c *CurlAction) Invoke(ctx context.Context, req action.InvokeRequest, resp

tflog.Debug(ctx, fmt.Sprintf("Invoke Action Call: \nURL: %s\nHeaders: %s\nMethod: %s\nRequest Body: %s\n", request.URL.String(), request.Header, request.Method, request.Body))

var responseCodes []string
for _, v := range data.ResponseCodes.Elements() {
if strVal, ok := v.(types.String); ok {
responseCodes = append(responseCodes, strVal.ValueString())
}
}

timeout := 10 * time.Second
if !data.Timeout.IsNull() {
timeout = time.Duration(data.Timeout.ValueInt64()) * time.Second
Expand All @@ -224,7 +216,7 @@ func (c *CurlAction) Invoke(ctx context.Context, req action.InvokeRequest, resp
_, _ = io.Copy(io.Discard, response.Body)
_ = response.Body.Close()

if responseCodeChecker(responseCodes, strconv.Itoa(statusCode)) {
if responseCodeChecker(data.ResponseCodes, statusCode) {
return
}

Expand Down
9 changes: 1 addition & 8 deletions internal/provider/curl_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,14 +277,7 @@ func (d *CurlDataSource) Read(ctx context.Context, req datasource.ReadRequest, r
bodyString = "{}"
}

var responseCodes []string
for _, v := range data.ResponseCodes.Elements() {
if strVal, ok := v.(types.String); ok {
responseCodes = append(responseCodes, strVal.ValueString())
}
}

if responseCodeChecker(responseCodes, strconv.Itoa(statusCode)) {
if responseCodeChecker(data.ResponseCodes, statusCode) {
break
}

Expand Down
29 changes: 3 additions & 26 deletions internal/provider/curl_ephemeral_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -517,14 +517,7 @@ func (e *EphemeralCurlResource) Open(ctx context.Context, req ephemeral.OpenRequ
bodyString = "{}"
}

var responseCodes []string
for _, v := range data.ResponseCodes.Elements() {
if strVal, ok := v.(types.String); ok {
responseCodes = append(responseCodes, strVal.ValueString())
}
}

if responseCodeChecker(responseCodes, strconv.Itoa(statusCode)) {
if responseCodeChecker(data.ResponseCodes, statusCode) {
break
}

Expand Down Expand Up @@ -1171,14 +1164,7 @@ func (e *EphemeralCurlResource) Renew(ctx context.Context, req ephemeral.RenewRe
bodyString = "{}"
}

var responseCodes []string
for _, v := range privateData.RenewResponseCodes.Elements() {
if strVal, ok := v.(types.String); ok {
responseCodes = append(responseCodes, strVal.ValueString())
}
}

if responseCodeChecker(responseCodes, strconv.Itoa(statusCode)) {
if responseCodeChecker(privateData.RenewResponseCodes, statusCode) {
break
}

Expand Down Expand Up @@ -1525,19 +1511,10 @@ func (e *EphemeralCurlResource) Close(ctx context.Context, req ephemeral.CloseRe
return
}

var expectedCodes []string
tflog.Debug(ctx, fmt.Sprintf("private data response code list: %v", privateData.CloseResponseCodes.Elements()))
for _, v := range privateData.CloseResponseCodes.Elements() {
if strVal, ok := v.(types.String); ok {
expectedCodes = append(expectedCodes, strVal.ValueString())
}
}

tflog.Debug(ctx, fmt.Sprintf("response code received: %v", statusCode))
tflog.Debug(ctx, fmt.Sprintf("expected response code received: %v", expectedCodes))

// Validate Response Code
if responseCodeChecker(expectedCodes, strconv.Itoa(statusCode)) {
if responseCodeChecker(privateData.CloseResponseCodes, statusCode) {
tflog.Debug(ctx, "Close request completed successfully")
break
} else {
Expand Down
20 changes: 3 additions & 17 deletions internal/provider/curl_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -577,14 +577,7 @@ func (r *CurlResource) Create(ctx context.Context, req resource.CreateRequest, r
bodyString = "{}"
}

var responseCodes []string
for _, v := range data.ResponseCodes.Elements() {
if strVal, ok := v.(types.String); ok {
responseCodes = append(responseCodes, strVal.ValueString())
}
}

if responseCodeChecker(responseCodes, strconv.Itoa(statusCode)) {
if responseCodeChecker(data.ResponseCodes, statusCode) {
break
}

Expand Down Expand Up @@ -739,7 +732,7 @@ func (r *CurlResource) Read(ctx context.Context, req resource.ReadRequest, resp
}

// Drift detection
if oldSanitized != sanitizedResponse {
if !responseCodeChecker(data.ReadResponseCodes, httpResp.StatusCode) || (oldSanitized != "null" && oldSanitized != sanitizedResponse) {
tflog.Warn(ctx, "Drift detected: Response has changed, marking for recreation.")
data.DriftMarker = types.StringValue(time.Now().Format(time.RFC3339Nano))
} else {
Expand Down Expand Up @@ -878,15 +871,8 @@ func (r *CurlResource) Delete(ctx context.Context, req resource.DeleteRequest, r
return
}

var expectedCodes []string
for _, v := range data.DestroyResponseCodes.Elements() {
if strVal, ok := v.(types.String); ok {
expectedCodes = append(expectedCodes, strVal.ValueString())
}
}

// Validate Response Code
if responseCodeChecker(expectedCodes, strconv.Itoa(statusCode)) {
if responseCodeChecker(data.DestroyResponseCodes, statusCode) {
tflog.Debug(ctx, "Destroy request completed successfully")
break
} else {
Expand Down
16 changes: 13 additions & 3 deletions internal/provider/utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http"
"net/url"
"os"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -115,9 +116,18 @@ func setDataSourceResponseValues(data *CurlDataSourceModel, body string) {
)
}

func responseCodeChecker(s []string, str string) bool {
for _, v := range s {
if v == str {
func responseCodeChecker(expectedStatusCodes types.List, receivedStatusCode int) bool {
var responseStatusCodes []string
for _, v := range expectedStatusCodes.Elements() {
if strVal, ok := v.(types.String); ok {
responseStatusCodes = append(responseStatusCodes, strVal.ValueString())
}
}

receivedStatusCodeAsInt := strconv.Itoa(receivedStatusCode)

for _, v := range responseStatusCodes {
if v == receivedStatusCodeAsInt {
return true
}
}
Expand Down
14 changes: 9 additions & 5 deletions internal/provider/utilities_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package provider

import (
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/types"
"io"
"net/http"
"net/http/httptest"
Expand Down Expand Up @@ -54,17 +56,19 @@ func TestSanitizeResponse(t *testing.T) {
func TestResponseCodeChecker(t *testing.T) {
tests := []struct {
name string
codes []string
input string
codes []attr.Value
input int
expected bool
}{
{"Value Present", []string{"200", "404", "500"}, "404", true},
{"Value Absent", []string{"200", "500"}, "404", false},
{"Value Present", []attr.Value{types.StringValue("200"), types.StringValue("404"), types.StringValue("500")}, 404, true},
{"Value Absent", []attr.Value{types.StringValue("200"), types.StringValue("500")}, 404, false},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := responseCodeChecker(tt.codes, tt.input)
var listValue types.List
listValue, _ = types.ListValue(types.StringType, tt.codes)
result := responseCodeChecker(listValue, tt.input)
if result != tt.expected {
t.Errorf("Expected %v, got %v", tt.expected, result)
}
Expand Down
Loading