Skip to content

Commit

Permalink
use validateFunc and expand validation
Browse files Browse the repository at this point in the history
  • Loading branch information
HantingZhang2 committed Jul 1, 2024
1 parent d7416e3 commit 6e18dcd
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 27 deletions.
54 changes: 35 additions & 19 deletions datadog/internal/validators/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strconv"
"strings"
"time"
"unicode"

"github.com/hashicorp/go-cty/cty"
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
Expand Down Expand Up @@ -304,26 +305,41 @@ func Float64Between(min, max float64) validator.String {
}
}

func ValidateHeaders(val any, p cty.Path) diag.Diagnostics {
var diags diag.Diagnostics
value := val.(map[string]interface{})
for _, v := range value {
valueString, ok := v.(string)
func ValidateHttpRequestHeader(v interface{}, k string) (ws []string, errors []error) {
value := v.(map[string]interface{})
for headerField, headerValue := range value {
if !isValidToken(headerField) {
errors = append(errors, fmt.Errorf("invalid value for %s (header field must be a valid token)", k))
return
}
headerStringValue, ok := headerValue.(string)
if !ok {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: "Invalid value",
Detail: "Synthetics test header must be a string",
AttributePath: p,
})
} else if strings.Contains(valueString, "\n") || strings.Contains(valueString, "\r\n") {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: "Invalid value",
Detail: "Synthetics test header must not contain newline characters",
AttributePath: p,
})
errors = append(errors, fmt.Errorf("expected type of %s to be string", k))
return
} else {
for _, r := range headerStringValue {
if (unicode.IsControl(r) && r != '\t') || (r == '\r' || r == '\n') {
errors = append(errors, fmt.Errorf("invalid value for %s (header value must not contain invisible characters)", k))
return
}
}
}
}
return diags
return
}

func isValidToken(token string) bool {
for _, r := range token {
if !isTokenChar(r) {
return false
}
}
return true
}

func isTokenChar(r rune) bool {
if r >= '!' && r <= '~' && !strings.ContainsRune("()<>@,;:\\\"/[]?={} \t", r) {
return true
}
return false
}
8 changes: 4 additions & 4 deletions datadog/resource_datadog_synthetics_test_.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,10 @@ func syntheticsTestRequest() *schema.Resource {

func syntheticsTestRequestHeaders() *schema.Schema {
return &schema.Schema{
Description: "Header name and value map.",
Type: schema.TypeMap,
ValidateDiagFunc: validators.ValidateHeaders,
Optional: true,
Description: "Header name and value map.",
Type: schema.TypeMap,
Optional: true,
ValidateFunc: validators.ValidateHttpRequestHeader,
}
}

Expand Down
8 changes: 4 additions & 4 deletions docs/resources/synthetics_test.md
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ resource "datadog_synthetics_test" "grpc" {
- `request_client_certificate` (Block List, Max: 1) Client certificate to use when performing the test request. Exactly one nested block is allowed with the structure below. (see [below for nested schema](#nestedblock--request_client_certificate))
- `request_definition` (Block List, Max: 1) Required if `type = "api"`. The synthetics test request. (see [below for nested schema](#nestedblock--request_definition))
- `request_file` (Block List) Files to be used as part of the request in the test. (see [below for nested schema](#nestedblock--request_file))
- `request_headers` (Map of String)
- `request_headers` (Map of String) Header name and value map.
- `request_metadata` (Map of String) Metadata to include when performing the gRPC test.
- `request_proxy` (Block List, Max: 1) The proxy to perform the test. (see [below for nested schema](#nestedblock--request_proxy))
- `request_query` (Map of String) Query arguments name and value map.
Expand Down Expand Up @@ -497,7 +497,7 @@ Optional:
- `request_client_certificate` (Block List, Max: 1) Client certificate to use when performing the test request. Exactly one nested block is allowed with the structure below. (see [below for nested schema](#nestedblock--api_step--request_client_certificate))
- `request_definition` (Block List, Max: 1) The request for the api step. (see [below for nested schema](#nestedblock--api_step--request_definition))
- `request_file` (Block List) Files to be used as part of the request in the test. (see [below for nested schema](#nestedblock--api_step--request_file))
- `request_headers` (Map of String)
- `request_headers` (Map of String) Header name and value map.
- `request_proxy` (Block List, Max: 1) The proxy to perform the test. (see [below for nested schema](#nestedblock--api_step--request_proxy))
- `request_query` (Map of String) Query arguments name and value map.
- `retry` (Block List, Max: 1) (see [below for nested schema](#nestedblock--api_step--retry))
Expand Down Expand Up @@ -702,7 +702,7 @@ Required:

Optional:

- `headers` (Map of String)
- `headers` (Map of String) Header name and value map.


<a id="nestedblock--api_step--retry"></a>
Expand Down Expand Up @@ -1082,7 +1082,7 @@ Required:

Optional:

- `headers` (Map of String)
- `headers` (Map of String) Header name and value map.

## Import

Expand Down

0 comments on commit 6e18dcd

Please sign in to comment.