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

[Synthetics] Support SSL #279

Merged
merged 14 commits into from
Aug 12, 2019
84 changes: 77 additions & 7 deletions datadog/resource_datadog_synthetics_test_.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
)

var syntheticsTypes = []string{"api", "browser"}
var syntheticsSubTypes = []string{"http", "ssl"}

func resourceDatadogSyntheticsTest() *schema.Resource {
return &schema.Resource{
Expand All @@ -30,6 +31,18 @@ func resourceDatadogSyntheticsTest() *schema.Resource {
Required: true,
ValidateFunc: validation.StringInSlice(syntheticsTypes, false),
},
"subtype": {
Type: schema.TypeString,
Optional: true,
DiffSuppressFunc: func(key, old, new string, d *schema.ResourceData) bool {
if d.Get("type") == "api" && old == "http" && new == "" {
// defaults to http if type is api for retro-compatibility
return true
}
return old == new
},
ValidateFunc: validation.StringInSlice(syntheticsSubTypes, false),
},
"request": syntheticsTestRequest(),
"request_headers": {
Type: schema.TypeMap,
Expand Down Expand Up @@ -89,11 +102,11 @@ func syntheticsTestRequest() *schema.Schema {
Schema: map[string]*schema.Schema{
"method": {
Type: schema.TypeString,
Required: true,
Optional: true,
},
"url": {
Type: schema.TypeString,
Required: true,
Optional: true,
},
"body": {
Type: schema.TypeString,
Expand All @@ -104,6 +117,15 @@ func syntheticsTestRequest() *schema.Schema {
Optional: true,
Default: 60,
},
"host": {
Type: schema.TypeString,
Optional: true,
},
"port": {
Type: schema.TypeInt,
Optional: true,
Default: 60,
},
},
},
}
Expand All @@ -113,9 +135,9 @@ func syntheticsTestOptions() *schema.Schema {
return &schema.Schema{
Type: schema.TypeMap,
DiffSuppressFunc: func(key, old, new string, d *schema.ResourceData) bool {
if key == "options.follow_redirects" {
if key == "options.follow_redirects" || key == "options.accept_self_signed" {
// TF nested schemas is limited to string values only
// follow_redirects being a boolean in Datadog json api
// follow_redirects and accept_self_signed being booleans in Datadog json api
// we need a sane way to convert from boolean to string
// and from string to boolean
oldValue, err1 := strconv.ParseBool(old)
Expand All @@ -133,11 +155,21 @@ func syntheticsTestOptions() *schema.Schema {
followRedirectsStr := convertToString(followRedirectsRaw)
switch followRedirectsStr {
case "0", "1":
warns = append(warns, fmt.Sprintf("%q must be either true or false, got: %s (please change 1 => true, 0 => false)", key, followRedirectsStr))
warns = append(warns, fmt.Sprintf("%q.follow_redirects must be either true or false, got: %s (please change 1 => true, 0 => false)", key, followRedirectsStr))
case "true", "false":
break
default:
errs = append(errs, fmt.Errorf("%q.follow_redirects must be either true or false, got: %s", key, followRedirectsStr))
}
}
acceptSelfSignedRaw, ok := val.(map[string]interface{})["accept_self_signed"]
if ok {
acceptSelfSignedStr := convertToString(acceptSelfSignedRaw)
switch acceptSelfSignedStr {
case "true", "false":
break
default:
errs = append(errs, fmt.Errorf("%q must be either true or false, got: %s", key, followRedirectsStr))
errs = append(errs, fmt.Errorf("%q.accept_self_signed must be either true or false, got: %s", key, acceptSelfSignedStr))
}
}
return
Expand All @@ -161,6 +193,10 @@ func syntheticsTestOptions() *schema.Schema {
Type: schema.TypeInt,
Required: true,
},
"accept_self_signed": {
Type: schema.TypeBool,
Optional: true,
},
},
},
}
Expand Down Expand Up @@ -228,7 +264,7 @@ func resourceDatadogSyntheticsTestDelete(d *schema.ResourceData, meta interface{
}

func isTargetOfTypeInt(assertionType string) bool {
for _, intTargetAssertionType := range []string{"responseTime", "statusCode"} {
for _, intTargetAssertionType := range []string{"responseTime", "statusCode", "certificate"} {
if assertionType == intTargetAssertionType {
return true
}
Expand All @@ -251,6 +287,13 @@ func newSyntheticsTestFromLocalState(d *schema.ResourceData) *datadog.Synthetics
timeoutInt, _ := strconv.Atoi(attr.(string))
request.SetTimeout(timeoutInt)
}
if attr, ok := d.GetOk("request.host"); ok {
request.SetHost(attr.(string))
}
if attr, ok := d.GetOk("request.port"); ok {
portInt, _ := strconv.Atoi(attr.(string))
request.SetPort(portInt)
}
if attr, ok := d.GetOk("request_headers"); ok {
headers := attr.(map[string]interface{})
if len(headers) > 0 {
Expand Down Expand Up @@ -316,6 +359,12 @@ func newSyntheticsTestFromLocalState(d *schema.ResourceData) *datadog.Synthetics
minLocationFailed, _ := strconv.Atoi(attr.(string))
options.SetMinLocationFailed(minLocationFailed)
}
if attr, ok := d.GetOk("options.accept_self_signed"); ok {
// for some reason, attr is equal to "1" or "0" in TF 0.11
// so ParseBool is required for retro-compatibility
acceptSelfSigned, _ := strconv.ParseBool(attr.(string))
options.SetAcceptSelfSigned(acceptSelfSigned)
}
if attr, ok := d.GetOk("device_ids"); ok {
deviceIds := []string{}
for _, s := range attr.([]interface{}) {
Expand Down Expand Up @@ -349,11 +398,23 @@ func newSyntheticsTestFromLocalState(d *schema.ResourceData) *datadog.Synthetics
}
syntheticsTest.Tags = tags

if attr, ok := d.GetOk("subtype"); ok {
syntheticsTest.Subtype = datadog.String(attr.(string))
} else {
if *syntheticsTest.Type == "api" {
// we want to default to "http" subtype when type is "api"
syntheticsTest.Subtype = datadog.String("http")
}
}

return &syntheticsTest
}

func updateSyntheticsTestLocalState(d *schema.ResourceData, syntheticsTest *datadog.SyntheticsTest) {
d.Set("type", syntheticsTest.GetType())
if syntheticsTest.HasSubtype() {
d.Set("subtype", syntheticsTest.GetSubtype())
}

actualRequest := syntheticsTest.GetConfig().Request
localRequest := make(map[string]string)
Expand All @@ -369,6 +430,12 @@ func updateSyntheticsTestLocalState(d *schema.ResourceData, syntheticsTest *data
if actualRequest.HasUrl() {
localRequest["url"] = actualRequest.GetUrl()
}
if actualRequest.HasHost() {
localRequest["host"] = actualRequest.GetHost()
}
if actualRequest.HasPort() {
localRequest["port"] = convertToString(actualRequest.GetPort())
}
d.Set("request", localRequest)
d.Set("request_headers", actualRequest.Headers)

Expand Down Expand Up @@ -410,6 +477,9 @@ func updateSyntheticsTestLocalState(d *schema.ResourceData, syntheticsTest *data
if actualOptions.HasTickEvery() {
localOptions["tick_every"] = convertToString(actualOptions.GetTickEvery())
}
if actualOptions.HasAcceptSelfSigned() {
localOptions["accept_self_signed"] = convertToString(actualOptions.GetAcceptSelfSigned())
}

d.Set("options", localOptions)

Expand Down
Loading