diff --git a/datadog/provider.go b/datadog/provider.go index b15e34aee0..e463573b14 100644 --- a/datadog/provider.go +++ b/datadog/provider.go @@ -35,6 +35,7 @@ func Provider() terraform.ResourceProvider { "datadog_downtime": resourceDatadogDowntime(), "datadog_metric_metadata": resourceDatadogMetricMetadata(), "datadog_monitor": resourceDatadogMonitor(), + "datadog_synthetics_test": resourceDatadogSyntheticsTest(), "datadog_timeboard": resourceDatadogTimeboard(), "datadog_screenboard": resourceDatadogScreenboard(), "datadog_user": resourceDatadogUser(), diff --git a/datadog/resource_datadog_synthetics_test_.go b/datadog/resource_datadog_synthetics_test_.go new file mode 100644 index 0000000000..05a18d9d6b --- /dev/null +++ b/datadog/resource_datadog_synthetics_test_.go @@ -0,0 +1,406 @@ +// For more info about writing custom provider: shttps://www.terraform.io/docs/extend/writing-custom-providers.html + +package datadog + +import ( + "encoding/json" + "fmt" + "strconv" + "strings" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + datadog "github.com/zorkian/go-datadog-api" +) + +var syntheticsTypes = []string{"api", "browser"} + +func resourceDatadogSyntheticsTest() *schema.Resource { + return &schema.Resource{ + Create: resourceDatadogSyntheticsTestCreate, + Read: resourceDatadogSyntheticsTestRead, + Update: resourceDatadogSyntheticsTestUpdate, + Delete: resourceDatadogSyntheticsTestDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(syntheticsTypes, false), + }, + "request": syntheticsTestRequest(), + "request_headers": { + Type: schema.TypeMap, + Optional: true, + }, + "assertions": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeMap, + }, + }, + "device_ids": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "locations": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "options": syntheticsTestOptions(), + "name": { + Type: schema.TypeString, + Required: true, + }, + "message": { + Type: schema.TypeString, + Optional: true, + Default: "", + }, + "tags": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "status": { + Type: schema.TypeString, + Required: true, + }, + }, + } +} + +func syntheticsTestRequest() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeMap, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "method": { + Type: schema.TypeString, + Required: true, + }, + "url": { + Type: schema.TypeString, + Required: true, + }, + "body": { + Type: schema.TypeString, + Optional: true, + }, + "timeout": { + Type: schema.TypeInt, + Optional: true, + Default: 60, + }, + }, + }, + } +} + +func syntheticsTestOptions() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "follow_redirects": { + Type: schema.TypeBool, + Optional: true, + }, + "min_failure_duration": { + Type: schema.TypeInt, + Optional: true, + }, + "min_location_failed": { + Type: schema.TypeInt, + Optional: true, + }, + "tick_every": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + } +} + +func resourceDatadogSyntheticsTestCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*datadog.Client) + + syntheticsTest := newSyntheticsTestFromLocalState(d) + createdSyntheticsTest, err := client.CreateSyntheticsTest(syntheticsTest) + if err != nil { + // Note that Id won't be set, so no state will be saved. + return fmt.Errorf("error creating synthetics test: %s", err.Error()) + } + + // If the Create callback returns with or without an error without an ID set using SetId, + // the resource is assumed to not be created, and no state is saved. + d.SetId(createdSyntheticsTest.GetPublicId()) + + // Return the read function to ensure the state is reflected in the terraform.state file + return resourceDatadogSyntheticsTestRead(d, meta) +} + +func resourceDatadogSyntheticsTestRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*datadog.Client) + + syntheticsTest, err := client.GetSyntheticsTest(d.Id()) + if err != nil { + if strings.Contains(err.Error(), "404 Not Found") { + // Delete the resource from the local state since it doesn't exist anymore in the actual state + d.SetId("") + return nil + } + return err + } + + updateSyntheticsTestLocalState(d, syntheticsTest) + + return nil +} + +func resourceDatadogSyntheticsTestUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*datadog.Client) + + syntheticsTest := newSyntheticsTestFromLocalState(d) + if _, err := client.UpdateSyntheticsTest(d.Id(), syntheticsTest); err != nil { + // If the Update callback returns with or without an error, the full state is saved. + return err + } + + // Return the read function to ensure the state is reflected in the terraform.state file + return resourceDatadogSyntheticsTestRead(d, meta) +} + +func resourceDatadogSyntheticsTestDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*datadog.Client) + + if err := client.DeleteSyntheticsTests([]string{d.Id()}); err != nil { + // The resource is assumed to still exist, and all prior state is preserved. + return err + } + + // The resource is assumed to be destroyed, and all state is removed. + return nil +} + +func isTargetOfTypeInt(assertionType string) bool { + for _, intTargetAssertionType := range []string{"responseTime", "statusCode"} { + if assertionType == intTargetAssertionType { + return true + } + } + return false +} + +func newSyntheticsTestFromLocalState(d *schema.ResourceData) *datadog.SyntheticsTest { + request := datadog.SyntheticsRequest{} + if attr, ok := d.GetOk("request.method"); ok { + request.SetMethod(attr.(string)) + } + if attr, ok := d.GetOk("request.url"); ok { + request.SetUrl(attr.(string)) + } + if attr, ok := d.GetOk("request.body"); ok { + request.SetBody(attr.(string)) + } + if attr, ok := d.GetOk("request.timeout"); ok { + timeoutInt, _ := strconv.Atoi(attr.(string)) + request.SetTimeout(timeoutInt) + } + if attr, ok := d.GetOk("request_headers"); ok { + headers := attr.(map[string]interface{}) + if len(headers) > 0 { + request.Headers = make(map[string]string) + } + for k, v := range headers { + request.Headers[k] = v.(string) + } + } + + config := datadog.SyntheticsConfig{ + Request: &request, + Variables: []interface{}{}, + } + + if attr, ok := d.GetOk("assertions"); ok { + for _, attr := range attr.([]interface{}) { + assertion := datadog.SyntheticsAssertion{} + assertionMap := attr.(map[string]interface{}) + if v, ok := assertionMap["type"]; ok { + assertionType := v.(string) + assertion.Type = &assertionType + } + if v, ok := assertionMap["property"]; ok { + assertionProperty := v.(string) + assertion.Property = &assertionProperty + } + if v, ok := assertionMap["operator"]; ok { + assertionOperator := v.(string) + assertion.Operator = &assertionOperator + } + if v, ok := assertionMap["target"]; ok { + if isTargetOfTypeInt(*assertion.Type) { + assertionTargetInt, _ := strconv.Atoi(v.(string)) + assertion.Target = assertionTargetInt + } else if *assertion.Operator == "validates" { + assertion.Target = json.RawMessage(v.(string)) + } else { + assertion.Target = v.(string) + } + } + config.Assertions = append(config.Assertions, assertion) + } + } + + options := datadog.SyntheticsOptions{} + if attr, ok := d.GetOk("options.tick_every"); ok { + tickEvery, _ := strconv.Atoi(attr.(string)) + options.SetTickEvery(tickEvery) + } + if attr, ok := d.GetOk("options.follow_redirects"); ok { + followRedirects := attr.(string) == "1" + options.SetFollowRedirects(followRedirects) + } + if attr, ok := d.GetOk("options.min_failure_duration"); ok { + minFailureDuration, _ := strconv.Atoi(attr.(string)) + options.SetMinFailureDuration(minFailureDuration) + } + if attr, ok := d.GetOk("options.min_location_failed"); ok { + minLocationFailed, _ := strconv.Atoi(attr.(string)) + options.SetMinLocationFailed(minLocationFailed) + } + if attr, ok := d.GetOk("device_ids"); ok { + deviceIds := []string{} + for _, s := range attr.([]interface{}) { + deviceIds = append(deviceIds, s.(string)) + } + options.DeviceIds = deviceIds + } + + syntheticsTest := datadog.SyntheticsTest{ + Name: datadog.String(d.Get("name").(string)), + Type: datadog.String(d.Get("type").(string)), + Config: &config, + Options: &options, + Message: datadog.String(d.Get("message").(string)), + Status: datadog.String(d.Get("status").(string)), + } + + if attr, ok := d.GetOk("locations"); ok { + locations := []string{} + for _, s := range attr.([]interface{}) { + locations = append(locations, s.(string)) + } + syntheticsTest.Locations = locations + } + + tags := []string{} + if attr, ok := d.GetOk("tags"); ok { + for _, s := range attr.([]interface{}) { + tags = append(tags, s.(string)) + } + } + syntheticsTest.Tags = tags + + return &syntheticsTest +} + +func updateSyntheticsTestLocalState(d *schema.ResourceData, syntheticsTest *datadog.SyntheticsTest) { + d.Set("type", syntheticsTest.GetType()) + + actualRequest := syntheticsTest.GetConfig().Request + localRequest := make(map[string]string) + if actualRequest.HasBody() { + localRequest["body"] = actualRequest.GetBody() + } + if actualRequest.HasMethod() { + localRequest["method"] = actualRequest.GetMethod() + } + if actualRequest.HasTimeout() { + localRequest["timeout"] = convertToString(actualRequest.GetTimeout()) + } + if actualRequest.HasUrl() { + localRequest["url"] = actualRequest.GetUrl() + } + d.Set("request", localRequest) + d.Set("request_headers", actualRequest.Headers) + + actualAssertions := syntheticsTest.GetConfig().Assertions + localAssertions := []map[string]string{} + for _, assertion := range actualAssertions { + localAssertion := make(map[string]string) + if assertion.HasOperator() { + localAssertion["operator"] = assertion.GetOperator() + } + if assertion.HasProperty() { + localAssertion["property"] = assertion.GetProperty() + } + if target := assertion.Target; target != nil { + localAssertion["target"] = convertToString(target) + } + if assertion.HasType() { + localAssertion["type"] = assertion.GetType() + } + localAssertions = append(localAssertions, localAssertion) + } + d.Set("assertions", localAssertions) + + d.Set("device_ids", syntheticsTest.GetOptions().DeviceIds) + + d.Set("locations", syntheticsTest.Locations) + + actualOptions := syntheticsTest.GetOptions() + localOptions := make(map[string]string) + if actualOptions.HasFollowRedirects() { + localOptions["follow_redirects"] = convertToString(actualOptions.GetFollowRedirects()) + } + if actualOptions.HasMinFailureDuration() { + localOptions["min_failure_duration"] = convertToString(actualOptions.GetMinFailureDuration()) + } + if actualOptions.HasMinLocationFailed() { + localOptions["min_location_failed"] = convertToString(actualOptions.GetMinLocationFailed()) + } + if actualOptions.HasTickEvery() { + localOptions["tick_every"] = convertToString(actualOptions.GetTickEvery()) + } + + d.Set("options", localOptions) + + d.Set("name", syntheticsTest.GetName()) + d.Set("message", syntheticsTest.GetMessage()) + d.Set("status", syntheticsTest.GetStatus()) + d.Set("tags", syntheticsTest.Tags) +} + +func convertToString(i interface{}) string { + switch v := i.(type) { + case bool: + if v { + return "1" + } + return "0" + case int: + return strconv.Itoa(v) + case float64: + return strconv.FormatFloat(v, 'f', -1, 64) + case string: + return v + default: + // TODO: manage target for JSON body assertions + valStrr, err := json.Marshal(v) + if err == nil { + return string(valStrr) + } + return "" + } +} diff --git a/datadog/resource_datadog_synthetics_test_test.go b/datadog/resource_datadog_synthetics_test_test.go new file mode 100644 index 0000000000..74436024c6 --- /dev/null +++ b/datadog/resource_datadog_synthetics_test_test.go @@ -0,0 +1,479 @@ +package datadog + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + datadog "github.com/zorkian/go-datadog-api" +) + +func TestAccDatadogSyntheticsAPITest_importBasic(t *testing.T) { + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testSyntheticsTestIsDestroyed, + Steps: []resource.TestStep{ + { + Config: createSyntheticsAPITestConfig, + }, + { + ResourceName: "datadog_synthetics_test.foo", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccDatadogSyntheticsBrowserTest_importBasic(t *testing.T) { + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testSyntheticsTestIsDestroyed, + Steps: []resource.TestStep{ + { + Config: createSyntheticsBrowserTestConfig, + }, + { + ResourceName: "datadog_synthetics_test.bar", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccDatadogSyntheticsAPITest_Basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testSyntheticsTestIsDestroyed, + Steps: []resource.TestStep{ + createSyntheticsAPITestStep, + }, + }) +} + +func TestAccDatadogSyntheticsAPITest_Updated(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testSyntheticsTestIsDestroyed, + Steps: []resource.TestStep{ + createSyntheticsAPITestStep, + updateSyntheticsAPITestStep, + }, + }) +} + +func TestAccDatadogSyntheticsBrowserTest_Basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testSyntheticsTestIsDestroyed, + Steps: []resource.TestStep{ + createSyntheticsBrowserTestStep, + }, + }) +} + +func TestAccDatadogSyntheticsBrowserTest_Updated(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testSyntheticsTestIsDestroyed, + Steps: []resource.TestStep{ + createSyntheticsBrowserTestStep, + updateSyntheticsBrowserTestStep, + }, + }) +} + +var createSyntheticsAPITestStep = resource.TestStep{ + Config: createSyntheticsAPITestConfig, + Check: resource.ComposeTestCheckFunc( + testSyntheticsTestExists(), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "type", "api"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "request.method", "GET"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "request.url", "https://www.datadoghq.com"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.#", "4"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.0.type", "header"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.0.property", "content-type"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.0.operator", "contains"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.0.target", "application/json"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.1.type", "statusCode"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.1.operator", "is"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.1.target", "200"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.2.type", "responseTime"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.2.operator", "lessThan"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.2.target", "2000"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.3.type", "body"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.3.operator", "doesNotContain"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.3.target", "terraform"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "locations.#", "1"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "locations.0", "aws:eu-central-1"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "options.tick_every", "60"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "options.min_failure_duration", "0"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "options.min_location_failed", "1"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "name", "name for synthetics test foo"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "message", "Notify @datadog.user"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "tags.#", "2"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "tags.0", "foo:bar"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "tags.1", "baz"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "status", "paused"), + ), +} + +const createSyntheticsAPITestConfig = ` +resource "datadog_synthetics_test" "foo" { + type = "api" + + request { + method = "GET" + url = "https://www.datadoghq.com" + body = "this is a body" + timeout = 30 + } + request_headers { + "Accept" = "application/json" + "X-Datadog-Trace-ID" = "1234566789" + } + + assertions = [ + { + type = "header" + property = "content-type" + operator = "contains" + target = "application/json" + }, + { + type = "statusCode" + operator = "is" + target = "200" + }, + { + type = "responseTime" + operator = "lessThan" + target = "2000" + }, + { + type = "body" + operator = "doesNotContain" + target = "terraform" + } + ] + + locations = [ "aws:eu-central-1" ] + options { + tick_every = 60 + min_failure_duration = 0 + min_location_failed = 1 + } + + name = "name for synthetics test foo" + message = "Notify @datadog.user" + tags = ["foo:bar", "baz"] + + status = "paused" +} +` + +var updateSyntheticsAPITestStep = resource.TestStep{ + Config: updateSyntheticsAPITestConfig, + Check: resource.ComposeTestCheckFunc( + testSyntheticsTestExists(), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "type", "api"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "request.method", "GET"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "request.url", "https://docs.datadoghq.com"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "request.timeout", "60"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.#", "1"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.0.type", "statusCode"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.0.operator", "isNot"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "assertions.0.target", "500"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "locations.#", "1"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "locations.0", "aws:eu-central-1"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "options.tick_every", "900"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "options.min_failure_duration", "10"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "options.min_location_failed", "1"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "name", "updated name"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "message", "Notify @pagerduty"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "tags.#", "3"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "tags.0", "foo:bar"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "tags.1", "foo"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "tags.2", "env:test"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.foo", "status", "live"), + ), +} + +const updateSyntheticsAPITestConfig = ` +resource "datadog_synthetics_test" "foo" { + type = "api" + + request { + method = "GET" + url = "https://docs.datadoghq.com" + timeout = 60 + } + + assertions = [ + { + type = "statusCode" + operator = "isNot" + target = "500" + } + ] + + locations = [ "aws:eu-central-1" ] + + options { + tick_every = 900 + min_failure_duration = 10 + min_location_failed = 1 + } + + name = "updated name" + message = "Notify @pagerduty" + tags = ["foo:bar", "foo", "env:test"] + + status = "live" +} +` + +var createSyntheticsBrowserTestStep = resource.TestStep{ + Config: createSyntheticsBrowserTestConfig, + Check: resource.ComposeTestCheckFunc( + testSyntheticsTestExists(), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "type", "browser"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "request.method", "GET"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "request.url", "https://www.datadoghq.com"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "request.body", "this is a body"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "request.timeout", "30"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "request_headers.%", "2"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "request_headers.Accept", "application/json"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "request_headers.X-Datadog-Trace-ID", "123456789"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "device_ids.#", "2"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "device_ids.0", "laptop_large"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "device_ids.1", "mobile_small"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "assertions.#", "0"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "locations.#", "1"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "locations.0", "aws:eu-central-1"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "options.tick_every", "900"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "options.min_failure_duration", "0"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "options.min_location_failed", "1"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "name", "name for synthetics browser test bar"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "message", "Notify @datadog.user"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "tags.#", "2"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "tags.0", "foo:bar"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "tags.1", "baz"), + ), +} + +const createSyntheticsBrowserTestConfig = ` +resource "datadog_synthetics_test" "bar" { + type = "browser" + + request { + method = "GET" + url = "https://www.datadoghq.com" + body = "this is a body" + timeout = 30 + } + request_headers { + "Accept" = "application/json" + "X-Datadog-Trace-ID" = "123456789" + } + + device_ids = [ "laptop_large", "mobile_small" ] + locations = [ "aws:eu-central-1" ] + options { + tick_every = 900 + min_failure_duration = 0 + min_location_failed = 1 + } + + name = "name for synthetics browser test bar" + message = "Notify @datadog.user" + tags = ["foo:bar", "baz"] + + status = "paused" +} +` + +var updateSyntheticsBrowserTestStep = resource.TestStep{ + Config: updateSyntheticsBrowserTestConfig, + Check: resource.ComposeTestCheckFunc( + testSyntheticsTestExists(), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "type", "browser"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "request.method", "PUT"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "request.url", "https://docs.datadoghq.com"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "request.body", "this is an updated body"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "request.timeout", "60"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "request_headers.%", "2"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "request_headers.Accept", "application/xml"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "request_headers.X-Datadog-Trace-ID", "987654321"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "device_ids.#", "2"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "device_ids.0", "laptop_large"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "device_ids.1", "tablet"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "assertions.#", "0"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "locations.#", "1"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "locations.0", "aws:eu-central-1"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "options.tick_every", "1800"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "options.min_failure_duration", "10"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "options.min_location_failed", "1"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "name", "updated name for synthetics browser test bar"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "message", "Notify @pagerduty"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "tags.#", "2"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "tags.0", "foo:bar"), + resource.TestCheckResourceAttr( + "datadog_synthetics_test.bar", "tags.1", "buz"), + ), +} + +const updateSyntheticsBrowserTestConfig = ` +resource "datadog_synthetics_test" "bar" { + type = "browser" + request { + method = "PUT" + url = "https://docs.datadoghq.com" + body = "this is an updated body" + timeout = 60 + } + request_headers { + "Accept" = "application/xml" + "X-Datadog-Trace-ID" = "987654321" + } + device_ids = [ "laptop_large", "tablet" ] + locations = [ "aws:eu-central-1" ] + options { + tick_every = 1800 + min_failure_duration = 10 + min_location_failed = 1 + } + name = "updated name for synthetics browser test bar" + message = "Notify @pagerduty" + tags = ["foo:bar", "buz"] + status = "live" +} +` + +func testSyntheticsTestExists() resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*datadog.Client) + + for _, r := range s.RootModule().Resources { + if _, err := client.GetSyntheticsTest(r.Primary.ID); err != nil { + return fmt.Errorf("Received an error retrieving synthetics test %s", err) + } + } + return nil + } +} + +func testSyntheticsTestIsDestroyed(s *terraform.State) error { + client := testAccProvider.Meta().(*datadog.Client) + + for _, r := range s.RootModule().Resources { + if _, err := client.GetSyntheticsTest(r.Primary.ID); err != nil { + if strings.Contains(err.Error(), "404 Not Found") { + continue + } + return fmt.Errorf("Received an error retrieving synthetics test %s", err) + } + return fmt.Errorf("Synthetics test still exists") + } + return nil +} diff --git a/go.mod b/go.mod index e46f8159f6..ffd9baeaf9 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ require ( github.com/blang/semver v3.5.1+incompatible // indirect github.com/cenkalti/backoff v0.0.0-20161020194410-b02f2bbce11d // indirect github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect + github.com/hashicorp/go-cleanhttp v0.5.0 github.com/hashicorp/go-getter v0.0.0-20180809191950-4bda8fa99001 // indirect github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f // indirect github.com/hashicorp/go-plugin v0.0.0-20181004024435-314501b665e0 // indirect @@ -19,7 +20,7 @@ require ( github.com/posener/complete v1.2.1 // indirect github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa // indirect github.com/zclconf/go-cty v0.0.0-20181017232614-01c5aba823a6 // indirect - github.com/zorkian/go-datadog-api v2.19.0+incompatible + github.com/zorkian/go-datadog-api v2.19.1-0.20190415084127-efa96fedb363+incompatible golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519 // indirect google.golang.org/genproto v0.0.0-20181016170114-94acd270e44e // indirect ) diff --git a/go.sum b/go.sum index e6b802d4d8..2342ed09dc 100644 --- a/go.sum +++ b/go.sum @@ -9,6 +9,14 @@ github.com/Azure/go-ntlmssp v0.0.0-20170803034930-c92175d54006/go.mod h1:chxPXzS github.com/ChrisTrenkamp/goxpath v0.0.0-20170625215350-4fe035839290 h1:K9I21XUHNbYD3GNMmJBN0UKJCpdP+glftwNZ7Bo8kqY= github.com/ChrisTrenkamp/goxpath v0.0.0-20170625215350-4fe035839290/go.mod h1:nuWgzSkT5PnyOd+272uUmV0dnAnAn42Mk7PiQC5VzN4= github.com/DHowett/go-plist v0.0.0-20180609054337-500bd5b9081b/go.mod h1:5paT5ZDrOm8eAJPem2Bd+q3FTi3Gxm/U4tb2tH8YIUQ= +github.com/DataDog/go-datadog-api v0.0.0-20190402145118-e4672b7066ac h1:2lpq/xj2C5pKzMPDRSLaakf7BomK3InPfcq42S/vAf4= +github.com/DataDog/go-datadog-api v0.0.0-20190402145118-e4672b7066ac/go.mod h1:M39kErhCx5HcdIQ1FA2NHJSWPA6qvUGkJ/Bhz6MAOa4= +github.com/DataDog/go-datadog-api v0.0.0-20190403100613-64d00d08241a h1:xutdLApqBruGT3dYCw+18pDWiYXRaHZxf94SaOB97Vc= +github.com/DataDog/go-datadog-api v0.0.0-20190403100613-64d00d08241a/go.mod h1:M39kErhCx5HcdIQ1FA2NHJSWPA6qvUGkJ/Bhz6MAOa4= +github.com/DataDog/go-datadog-api v0.0.0-20190409090430-627e185509df h1:hUKMb79rABpaespgHpSekKoALS47XPID/Ni6fRfmivo= +github.com/DataDog/go-datadog-api v0.0.0-20190409090430-627e185509df/go.mod h1:M39kErhCx5HcdIQ1FA2NHJSWPA6qvUGkJ/Bhz6MAOa4= +github.com/DataDog/go-datadog-api v0.0.0-20190409155204-5497235f061d h1:qWou04uTL243M06V6n7CB4LadBxNPGhv/TREJa9OVik= +github.com/DataDog/go-datadog-api v0.0.0-20190409155204-5497235f061d/go.mod h1:M39kErhCx5HcdIQ1FA2NHJSWPA6qvUGkJ/Bhz6MAOa4= github.com/Unknwon/com v0.0.0-20151008135407-28b053d5a292 h1:tuQ7w+my8a8mkwN7x2TSd7OzTjkZ7rAeSyH4xncuAMI= github.com/Unknwon/com v0.0.0-20151008135407-28b053d5a292/go.mod h1:KYCjqMOeHpNuTOiFQU6WEcTG7poCJrUs0YgyHNtn1no= github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw= @@ -293,8 +301,8 @@ github.com/zclconf/go-cty v0.0.0-20180302160414-49fa5e03c418/go.mod h1:LnDKxj8gN github.com/zclconf/go-cty v0.0.0-20180815031001-58bb2bc0302a/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v0.0.0-20181017232614-01c5aba823a6 h1:Y9SzKuDy2J5QLFPmFk7/ZIzbu4/FrQK9Zwv4vjivNiM= github.com/zclconf/go-cty v0.0.0-20181017232614-01c5aba823a6/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= -github.com/zorkian/go-datadog-api v2.19.0+incompatible h1:G17NtfeHwrsQ2degevkwiVEirZENSOjbGOjLLT/kwa4= -github.com/zorkian/go-datadog-api v2.19.0+incompatible/go.mod h1:PkXwHX9CUQa/FpB9ZwAD45N1uhCW4MT/Wj7m36PbKss= +github.com/zorkian/go-datadog-api v2.19.1-0.20190415084127-efa96fedb363+incompatible h1:uQBFFHBO8CiSo/Gp4E7vzE6cj2TTtZ/SuGO4nDyCY3g= +github.com/zorkian/go-datadog-api v2.19.1-0.20190415084127-efa96fedb363+incompatible/go.mod h1:PkXwHX9CUQa/FpB9ZwAD45N1uhCW4MT/Wj7m36PbKss= golang.org/x/crypto v0.0.0-20180211211603-9de5f2eaf759/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180816225734-aabede6cba87 h1:gCHhzI+1R9peHIMyiWVxoVaWlk1cYK7VThX5ptLtbXY= golang.org/x/crypto v0.0.0-20180816225734-aabede6cba87/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/vendor/github.com/zorkian/go-datadog-api/README.md b/vendor/github.com/zorkian/go-datadog-api/README.md index b9d7fcbf95..73dd9cecc0 100644 --- a/vendor/github.com/zorkian/go-datadog-api/README.md +++ b/vendor/github.com/zorkian/go-datadog-api/README.md @@ -117,4 +117,4 @@ make generate Please see the LICENSE file for the included license information. -Copyright 2013-2017 by authors and contributors. +Copyright 2013-2019 by authors and contributors. diff --git a/vendor/github.com/zorkian/go-datadog-api/datadog-accessors.go b/vendor/github.com/zorkian/go-datadog-api/datadog-accessors.go index d08aacba3a..4dc457448a 100644 --- a/vendor/github.com/zorkian/go-datadog-api/datadog-accessors.go +++ b/vendor/github.com/zorkian/go-datadog-api/datadog-accessors.go @@ -7329,6 +7329,1277 @@ func (s *Style) SetPaletteFlip(v bool) { s.PaletteFlip = &v } +// GetOperator returns the Operator field if non-nil, zero value otherwise. +func (s *SyntheticsAssertion) GetOperator() string { + if s == nil || s.Operator == nil { + return "" + } + return *s.Operator +} + +// GetOperatorOk returns a tuple with the Operator field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsAssertion) GetOperatorOk() (string, bool) { + if s == nil || s.Operator == nil { + return "", false + } + return *s.Operator, true +} + +// HasOperator returns a boolean if a field has been set. +func (s *SyntheticsAssertion) HasOperator() bool { + if s != nil && s.Operator != nil { + return true + } + + return false +} + +// SetOperator allocates a new s.Operator and returns the pointer to it. +func (s *SyntheticsAssertion) SetOperator(v string) { + s.Operator = &v +} + +// GetProperty returns the Property field if non-nil, zero value otherwise. +func (s *SyntheticsAssertion) GetProperty() string { + if s == nil || s.Property == nil { + return "" + } + return *s.Property +} + +// GetPropertyOk returns a tuple with the Property field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsAssertion) GetPropertyOk() (string, bool) { + if s == nil || s.Property == nil { + return "", false + } + return *s.Property, true +} + +// HasProperty returns a boolean if a field has been set. +func (s *SyntheticsAssertion) HasProperty() bool { + if s != nil && s.Property != nil { + return true + } + + return false +} + +// SetProperty allocates a new s.Property and returns the pointer to it. +func (s *SyntheticsAssertion) SetProperty(v string) { + s.Property = &v +} + +// GetType returns the Type field if non-nil, zero value otherwise. +func (s *SyntheticsAssertion) GetType() string { + if s == nil || s.Type == nil { + return "" + } + return *s.Type +} + +// GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsAssertion) GetTypeOk() (string, bool) { + if s == nil || s.Type == nil { + return "", false + } + return *s.Type, true +} + +// HasType returns a boolean if a field has been set. +func (s *SyntheticsAssertion) HasType() bool { + if s != nil && s.Type != nil { + return true + } + + return false +} + +// SetType allocates a new s.Type and returns the pointer to it. +func (s *SyntheticsAssertion) SetType(v string) { + s.Type = &v +} + +// GetRequest returns the Request field if non-nil, zero value otherwise. +func (s *SyntheticsConfig) GetRequest() SyntheticsRequest { + if s == nil || s.Request == nil { + return SyntheticsRequest{} + } + return *s.Request +} + +// GetRequestOk returns a tuple with the Request field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsConfig) GetRequestOk() (SyntheticsRequest, bool) { + if s == nil || s.Request == nil { + return SyntheticsRequest{}, false + } + return *s.Request, true +} + +// HasRequest returns a boolean if a field has been set. +func (s *SyntheticsConfig) HasRequest() bool { + if s != nil && s.Request != nil { + return true + } + + return false +} + +// SetRequest allocates a new s.Request and returns the pointer to it. +func (s *SyntheticsConfig) SetRequest(v SyntheticsRequest) { + s.Request = &v +} + +// GetHeight returns the Height field if non-nil, zero value otherwise. +func (s *SyntheticsDevice) GetHeight() int { + if s == nil || s.Height == nil { + return 0 + } + return *s.Height +} + +// GetHeightOk returns a tuple with the Height field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsDevice) GetHeightOk() (int, bool) { + if s == nil || s.Height == nil { + return 0, false + } + return *s.Height, true +} + +// HasHeight returns a boolean if a field has been set. +func (s *SyntheticsDevice) HasHeight() bool { + if s != nil && s.Height != nil { + return true + } + + return false +} + +// SetHeight allocates a new s.Height and returns the pointer to it. +func (s *SyntheticsDevice) SetHeight(v int) { + s.Height = &v +} + +// GetId returns the Id field if non-nil, zero value otherwise. +func (s *SyntheticsDevice) GetId() string { + if s == nil || s.Id == nil { + return "" + } + return *s.Id +} + +// GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsDevice) GetIdOk() (string, bool) { + if s == nil || s.Id == nil { + return "", false + } + return *s.Id, true +} + +// HasId returns a boolean if a field has been set. +func (s *SyntheticsDevice) HasId() bool { + if s != nil && s.Id != nil { + return true + } + + return false +} + +// SetId allocates a new s.Id and returns the pointer to it. +func (s *SyntheticsDevice) SetId(v string) { + s.Id = &v +} + +// GetIsLandscape returns the IsLandscape field if non-nil, zero value otherwise. +func (s *SyntheticsDevice) GetIsLandscape() bool { + if s == nil || s.IsLandscape == nil { + return false + } + return *s.IsLandscape +} + +// GetIsLandscapeOk returns a tuple with the IsLandscape field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsDevice) GetIsLandscapeOk() (bool, bool) { + if s == nil || s.IsLandscape == nil { + return false, false + } + return *s.IsLandscape, true +} + +// HasIsLandscape returns a boolean if a field has been set. +func (s *SyntheticsDevice) HasIsLandscape() bool { + if s != nil && s.IsLandscape != nil { + return true + } + + return false +} + +// SetIsLandscape allocates a new s.IsLandscape and returns the pointer to it. +func (s *SyntheticsDevice) SetIsLandscape(v bool) { + s.IsLandscape = &v +} + +// GetIsMobile returns the IsMobile field if non-nil, zero value otherwise. +func (s *SyntheticsDevice) GetIsMobile() bool { + if s == nil || s.IsMobile == nil { + return false + } + return *s.IsMobile +} + +// GetIsMobileOk returns a tuple with the IsMobile field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsDevice) GetIsMobileOk() (bool, bool) { + if s == nil || s.IsMobile == nil { + return false, false + } + return *s.IsMobile, true +} + +// HasIsMobile returns a boolean if a field has been set. +func (s *SyntheticsDevice) HasIsMobile() bool { + if s != nil && s.IsMobile != nil { + return true + } + + return false +} + +// SetIsMobile allocates a new s.IsMobile and returns the pointer to it. +func (s *SyntheticsDevice) SetIsMobile(v bool) { + s.IsMobile = &v +} + +// GetName returns the Name field if non-nil, zero value otherwise. +func (s *SyntheticsDevice) GetName() string { + if s == nil || s.Name == nil { + return "" + } + return *s.Name +} + +// GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsDevice) GetNameOk() (string, bool) { + if s == nil || s.Name == nil { + return "", false + } + return *s.Name, true +} + +// HasName returns a boolean if a field has been set. +func (s *SyntheticsDevice) HasName() bool { + if s != nil && s.Name != nil { + return true + } + + return false +} + +// SetName allocates a new s.Name and returns the pointer to it. +func (s *SyntheticsDevice) SetName(v string) { + s.Name = &v +} + +// GetUserAgent returns the UserAgent field if non-nil, zero value otherwise. +func (s *SyntheticsDevice) GetUserAgent() string { + if s == nil || s.UserAgent == nil { + return "" + } + return *s.UserAgent +} + +// GetUserAgentOk returns a tuple with the UserAgent field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsDevice) GetUserAgentOk() (string, bool) { + if s == nil || s.UserAgent == nil { + return "", false + } + return *s.UserAgent, true +} + +// HasUserAgent returns a boolean if a field has been set. +func (s *SyntheticsDevice) HasUserAgent() bool { + if s != nil && s.UserAgent != nil { + return true + } + + return false +} + +// SetUserAgent allocates a new s.UserAgent and returns the pointer to it. +func (s *SyntheticsDevice) SetUserAgent(v string) { + s.UserAgent = &v +} + +// GetWidth returns the Width field if non-nil, zero value otherwise. +func (s *SyntheticsDevice) GetWidth() int { + if s == nil || s.Width == nil { + return 0 + } + return *s.Width +} + +// GetWidthOk returns a tuple with the Width field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsDevice) GetWidthOk() (int, bool) { + if s == nil || s.Width == nil { + return 0, false + } + return *s.Width, true +} + +// HasWidth returns a boolean if a field has been set. +func (s *SyntheticsDevice) HasWidth() bool { + if s != nil && s.Width != nil { + return true + } + + return false +} + +// SetWidth allocates a new s.Width and returns the pointer to it. +func (s *SyntheticsDevice) SetWidth(v int) { + s.Width = &v +} + +// GetDisplayName returns the DisplayName field if non-nil, zero value otherwise. +func (s *SyntheticsLocation) GetDisplayName() string { + if s == nil || s.DisplayName == nil { + return "" + } + return *s.DisplayName +} + +// GetDisplayNameOk returns a tuple with the DisplayName field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsLocation) GetDisplayNameOk() (string, bool) { + if s == nil || s.DisplayName == nil { + return "", false + } + return *s.DisplayName, true +} + +// HasDisplayName returns a boolean if a field has been set. +func (s *SyntheticsLocation) HasDisplayName() bool { + if s != nil && s.DisplayName != nil { + return true + } + + return false +} + +// SetDisplayName allocates a new s.DisplayName and returns the pointer to it. +func (s *SyntheticsLocation) SetDisplayName(v string) { + s.DisplayName = &v +} + +// GetId returns the Id field if non-nil, zero value otherwise. +func (s *SyntheticsLocation) GetId() int { + if s == nil || s.Id == nil { + return 0 + } + return *s.Id +} + +// GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsLocation) GetIdOk() (int, bool) { + if s == nil || s.Id == nil { + return 0, false + } + return *s.Id, true +} + +// HasId returns a boolean if a field has been set. +func (s *SyntheticsLocation) HasId() bool { + if s != nil && s.Id != nil { + return true + } + + return false +} + +// SetId allocates a new s.Id and returns the pointer to it. +func (s *SyntheticsLocation) SetId(v int) { + s.Id = &v +} + +// GetIsLandscape returns the IsLandscape field if non-nil, zero value otherwise. +func (s *SyntheticsLocation) GetIsLandscape() bool { + if s == nil || s.IsLandscape == nil { + return false + } + return *s.IsLandscape +} + +// GetIsLandscapeOk returns a tuple with the IsLandscape field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsLocation) GetIsLandscapeOk() (bool, bool) { + if s == nil || s.IsLandscape == nil { + return false, false + } + return *s.IsLandscape, true +} + +// HasIsLandscape returns a boolean if a field has been set. +func (s *SyntheticsLocation) HasIsLandscape() bool { + if s != nil && s.IsLandscape != nil { + return true + } + + return false +} + +// SetIsLandscape allocates a new s.IsLandscape and returns the pointer to it. +func (s *SyntheticsLocation) SetIsLandscape(v bool) { + s.IsLandscape = &v +} + +// GetName returns the Name field if non-nil, zero value otherwise. +func (s *SyntheticsLocation) GetName() string { + if s == nil || s.Name == nil { + return "" + } + return *s.Name +} + +// GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsLocation) GetNameOk() (string, bool) { + if s == nil || s.Name == nil { + return "", false + } + return *s.Name, true +} + +// HasName returns a boolean if a field has been set. +func (s *SyntheticsLocation) HasName() bool { + if s != nil && s.Name != nil { + return true + } + + return false +} + +// SetName allocates a new s.Name and returns the pointer to it. +func (s *SyntheticsLocation) SetName(v string) { + s.Name = &v +} + +// GetRegion returns the Region field if non-nil, zero value otherwise. +func (s *SyntheticsLocation) GetRegion() string { + if s == nil || s.Region == nil { + return "" + } + return *s.Region +} + +// GetRegionOk returns a tuple with the Region field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsLocation) GetRegionOk() (string, bool) { + if s == nil || s.Region == nil { + return "", false + } + return *s.Region, true +} + +// HasRegion returns a boolean if a field has been set. +func (s *SyntheticsLocation) HasRegion() bool { + if s != nil && s.Region != nil { + return true + } + + return false +} + +// SetRegion allocates a new s.Region and returns the pointer to it. +func (s *SyntheticsLocation) SetRegion(v string) { + s.Region = &v +} + +// GetFollowRedirects returns the FollowRedirects field if non-nil, zero value otherwise. +func (s *SyntheticsOptions) GetFollowRedirects() bool { + if s == nil || s.FollowRedirects == nil { + return false + } + return *s.FollowRedirects +} + +// GetFollowRedirectsOk returns a tuple with the FollowRedirects field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsOptions) GetFollowRedirectsOk() (bool, bool) { + if s == nil || s.FollowRedirects == nil { + return false, false + } + return *s.FollowRedirects, true +} + +// HasFollowRedirects returns a boolean if a field has been set. +func (s *SyntheticsOptions) HasFollowRedirects() bool { + if s != nil && s.FollowRedirects != nil { + return true + } + + return false +} + +// SetFollowRedirects allocates a new s.FollowRedirects and returns the pointer to it. +func (s *SyntheticsOptions) SetFollowRedirects(v bool) { + s.FollowRedirects = &v +} + +// GetMinFailureDuration returns the MinFailureDuration field if non-nil, zero value otherwise. +func (s *SyntheticsOptions) GetMinFailureDuration() int { + if s == nil || s.MinFailureDuration == nil { + return 0 + } + return *s.MinFailureDuration +} + +// GetMinFailureDurationOk returns a tuple with the MinFailureDuration field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsOptions) GetMinFailureDurationOk() (int, bool) { + if s == nil || s.MinFailureDuration == nil { + return 0, false + } + return *s.MinFailureDuration, true +} + +// HasMinFailureDuration returns a boolean if a field has been set. +func (s *SyntheticsOptions) HasMinFailureDuration() bool { + if s != nil && s.MinFailureDuration != nil { + return true + } + + return false +} + +// SetMinFailureDuration allocates a new s.MinFailureDuration and returns the pointer to it. +func (s *SyntheticsOptions) SetMinFailureDuration(v int) { + s.MinFailureDuration = &v +} + +// GetMinLocationFailed returns the MinLocationFailed field if non-nil, zero value otherwise. +func (s *SyntheticsOptions) GetMinLocationFailed() int { + if s == nil || s.MinLocationFailed == nil { + return 0 + } + return *s.MinLocationFailed +} + +// GetMinLocationFailedOk returns a tuple with the MinLocationFailed field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsOptions) GetMinLocationFailedOk() (int, bool) { + if s == nil || s.MinLocationFailed == nil { + return 0, false + } + return *s.MinLocationFailed, true +} + +// HasMinLocationFailed returns a boolean if a field has been set. +func (s *SyntheticsOptions) HasMinLocationFailed() bool { + if s != nil && s.MinLocationFailed != nil { + return true + } + + return false +} + +// SetMinLocationFailed allocates a new s.MinLocationFailed and returns the pointer to it. +func (s *SyntheticsOptions) SetMinLocationFailed(v int) { + s.MinLocationFailed = &v +} + +// GetTickEvery returns the TickEvery field if non-nil, zero value otherwise. +func (s *SyntheticsOptions) GetTickEvery() int { + if s == nil || s.TickEvery == nil { + return 0 + } + return *s.TickEvery +} + +// GetTickEveryOk returns a tuple with the TickEvery field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsOptions) GetTickEveryOk() (int, bool) { + if s == nil || s.TickEvery == nil { + return 0, false + } + return *s.TickEvery, true +} + +// HasTickEvery returns a boolean if a field has been set. +func (s *SyntheticsOptions) HasTickEvery() bool { + if s != nil && s.TickEvery != nil { + return true + } + + return false +} + +// SetTickEvery allocates a new s.TickEvery and returns the pointer to it. +func (s *SyntheticsOptions) SetTickEvery(v int) { + s.TickEvery = &v +} + +// GetBody returns the Body field if non-nil, zero value otherwise. +func (s *SyntheticsRequest) GetBody() string { + if s == nil || s.Body == nil { + return "" + } + return *s.Body +} + +// GetBodyOk returns a tuple with the Body field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsRequest) GetBodyOk() (string, bool) { + if s == nil || s.Body == nil { + return "", false + } + return *s.Body, true +} + +// HasBody returns a boolean if a field has been set. +func (s *SyntheticsRequest) HasBody() bool { + if s != nil && s.Body != nil { + return true + } + + return false +} + +// SetBody allocates a new s.Body and returns the pointer to it. +func (s *SyntheticsRequest) SetBody(v string) { + s.Body = &v +} + +// GetMethod returns the Method field if non-nil, zero value otherwise. +func (s *SyntheticsRequest) GetMethod() string { + if s == nil || s.Method == nil { + return "" + } + return *s.Method +} + +// GetMethodOk returns a tuple with the Method field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsRequest) GetMethodOk() (string, bool) { + if s == nil || s.Method == nil { + return "", false + } + return *s.Method, true +} + +// HasMethod returns a boolean if a field has been set. +func (s *SyntheticsRequest) HasMethod() bool { + if s != nil && s.Method != nil { + return true + } + + return false +} + +// SetMethod allocates a new s.Method and returns the pointer to it. +func (s *SyntheticsRequest) SetMethod(v string) { + s.Method = &v +} + +// GetTimeout returns the Timeout field if non-nil, zero value otherwise. +func (s *SyntheticsRequest) GetTimeout() int { + if s == nil || s.Timeout == nil { + return 0 + } + return *s.Timeout +} + +// GetTimeoutOk returns a tuple with the Timeout field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsRequest) GetTimeoutOk() (int, bool) { + if s == nil || s.Timeout == nil { + return 0, false + } + return *s.Timeout, true +} + +// HasTimeout returns a boolean if a field has been set. +func (s *SyntheticsRequest) HasTimeout() bool { + if s != nil && s.Timeout != nil { + return true + } + + return false +} + +// SetTimeout allocates a new s.Timeout and returns the pointer to it. +func (s *SyntheticsRequest) SetTimeout(v int) { + s.Timeout = &v +} + +// GetUrl returns the Url field if non-nil, zero value otherwise. +func (s *SyntheticsRequest) GetUrl() string { + if s == nil || s.Url == nil { + return "" + } + return *s.Url +} + +// GetUrlOk returns a tuple with the Url field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsRequest) GetUrlOk() (string, bool) { + if s == nil || s.Url == nil { + return "", false + } + return *s.Url, true +} + +// HasUrl returns a boolean if a field has been set. +func (s *SyntheticsRequest) HasUrl() bool { + if s != nil && s.Url != nil { + return true + } + + return false +} + +// SetUrl allocates a new s.Url and returns the pointer to it. +func (s *SyntheticsRequest) SetUrl(v string) { + s.Url = &v +} + +// GetConfig returns the Config field if non-nil, zero value otherwise. +func (s *SyntheticsTest) GetConfig() SyntheticsConfig { + if s == nil || s.Config == nil { + return SyntheticsConfig{} + } + return *s.Config +} + +// GetConfigOk returns a tuple with the Config field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsTest) GetConfigOk() (SyntheticsConfig, bool) { + if s == nil || s.Config == nil { + return SyntheticsConfig{}, false + } + return *s.Config, true +} + +// HasConfig returns a boolean if a field has been set. +func (s *SyntheticsTest) HasConfig() bool { + if s != nil && s.Config != nil { + return true + } + + return false +} + +// SetConfig allocates a new s.Config and returns the pointer to it. +func (s *SyntheticsTest) SetConfig(v SyntheticsConfig) { + s.Config = &v +} + +// GetCreatedAt returns the CreatedAt field if non-nil, zero value otherwise. +func (s *SyntheticsTest) GetCreatedAt() string { + if s == nil || s.CreatedAt == nil { + return "" + } + return *s.CreatedAt +} + +// GetCreatedAtOk returns a tuple with the CreatedAt field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsTest) GetCreatedAtOk() (string, bool) { + if s == nil || s.CreatedAt == nil { + return "", false + } + return *s.CreatedAt, true +} + +// HasCreatedAt returns a boolean if a field has been set. +func (s *SyntheticsTest) HasCreatedAt() bool { + if s != nil && s.CreatedAt != nil { + return true + } + + return false +} + +// SetCreatedAt allocates a new s.CreatedAt and returns the pointer to it. +func (s *SyntheticsTest) SetCreatedAt(v string) { + s.CreatedAt = &v +} + +// GetCreatedBy returns the CreatedBy field if non-nil, zero value otherwise. +func (s *SyntheticsTest) GetCreatedBy() SyntheticsUser { + if s == nil || s.CreatedBy == nil { + return SyntheticsUser{} + } + return *s.CreatedBy +} + +// GetCreatedByOk returns a tuple with the CreatedBy field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsTest) GetCreatedByOk() (SyntheticsUser, bool) { + if s == nil || s.CreatedBy == nil { + return SyntheticsUser{}, false + } + return *s.CreatedBy, true +} + +// HasCreatedBy returns a boolean if a field has been set. +func (s *SyntheticsTest) HasCreatedBy() bool { + if s != nil && s.CreatedBy != nil { + return true + } + + return false +} + +// SetCreatedBy allocates a new s.CreatedBy and returns the pointer to it. +func (s *SyntheticsTest) SetCreatedBy(v SyntheticsUser) { + s.CreatedBy = &v +} + +// GetDeletedAt returns the DeletedAt field if non-nil, zero value otherwise. +func (s *SyntheticsTest) GetDeletedAt() string { + if s == nil || s.DeletedAt == nil { + return "" + } + return *s.DeletedAt +} + +// GetDeletedAtOk returns a tuple with the DeletedAt field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsTest) GetDeletedAtOk() (string, bool) { + if s == nil || s.DeletedAt == nil { + return "", false + } + return *s.DeletedAt, true +} + +// HasDeletedAt returns a boolean if a field has been set. +func (s *SyntheticsTest) HasDeletedAt() bool { + if s != nil && s.DeletedAt != nil { + return true + } + + return false +} + +// SetDeletedAt allocates a new s.DeletedAt and returns the pointer to it. +func (s *SyntheticsTest) SetDeletedAt(v string) { + s.DeletedAt = &v +} + +// GetMessage returns the Message field if non-nil, zero value otherwise. +func (s *SyntheticsTest) GetMessage() string { + if s == nil || s.Message == nil { + return "" + } + return *s.Message +} + +// GetMessageOk returns a tuple with the Message field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsTest) GetMessageOk() (string, bool) { + if s == nil || s.Message == nil { + return "", false + } + return *s.Message, true +} + +// HasMessage returns a boolean if a field has been set. +func (s *SyntheticsTest) HasMessage() bool { + if s != nil && s.Message != nil { + return true + } + + return false +} + +// SetMessage allocates a new s.Message and returns the pointer to it. +func (s *SyntheticsTest) SetMessage(v string) { + s.Message = &v +} + +// GetModifiedAt returns the ModifiedAt field if non-nil, zero value otherwise. +func (s *SyntheticsTest) GetModifiedAt() string { + if s == nil || s.ModifiedAt == nil { + return "" + } + return *s.ModifiedAt +} + +// GetModifiedAtOk returns a tuple with the ModifiedAt field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsTest) GetModifiedAtOk() (string, bool) { + if s == nil || s.ModifiedAt == nil { + return "", false + } + return *s.ModifiedAt, true +} + +// HasModifiedAt returns a boolean if a field has been set. +func (s *SyntheticsTest) HasModifiedAt() bool { + if s != nil && s.ModifiedAt != nil { + return true + } + + return false +} + +// SetModifiedAt allocates a new s.ModifiedAt and returns the pointer to it. +func (s *SyntheticsTest) SetModifiedAt(v string) { + s.ModifiedAt = &v +} + +// GetModifiedBy returns the ModifiedBy field if non-nil, zero value otherwise. +func (s *SyntheticsTest) GetModifiedBy() SyntheticsUser { + if s == nil || s.ModifiedBy == nil { + return SyntheticsUser{} + } + return *s.ModifiedBy +} + +// GetModifiedByOk returns a tuple with the ModifiedBy field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsTest) GetModifiedByOk() (SyntheticsUser, bool) { + if s == nil || s.ModifiedBy == nil { + return SyntheticsUser{}, false + } + return *s.ModifiedBy, true +} + +// HasModifiedBy returns a boolean if a field has been set. +func (s *SyntheticsTest) HasModifiedBy() bool { + if s != nil && s.ModifiedBy != nil { + return true + } + + return false +} + +// SetModifiedBy allocates a new s.ModifiedBy and returns the pointer to it. +func (s *SyntheticsTest) SetModifiedBy(v SyntheticsUser) { + s.ModifiedBy = &v +} + +// GetMonitorStatus returns the MonitorStatus field if non-nil, zero value otherwise. +func (s *SyntheticsTest) GetMonitorStatus() string { + if s == nil || s.MonitorStatus == nil { + return "" + } + return *s.MonitorStatus +} + +// GetMonitorStatusOk returns a tuple with the MonitorStatus field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsTest) GetMonitorStatusOk() (string, bool) { + if s == nil || s.MonitorStatus == nil { + return "", false + } + return *s.MonitorStatus, true +} + +// HasMonitorStatus returns a boolean if a field has been set. +func (s *SyntheticsTest) HasMonitorStatus() bool { + if s != nil && s.MonitorStatus != nil { + return true + } + + return false +} + +// SetMonitorStatus allocates a new s.MonitorStatus and returns the pointer to it. +func (s *SyntheticsTest) SetMonitorStatus(v string) { + s.MonitorStatus = &v +} + +// GetName returns the Name field if non-nil, zero value otherwise. +func (s *SyntheticsTest) GetName() string { + if s == nil || s.Name == nil { + return "" + } + return *s.Name +} + +// GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsTest) GetNameOk() (string, bool) { + if s == nil || s.Name == nil { + return "", false + } + return *s.Name, true +} + +// HasName returns a boolean if a field has been set. +func (s *SyntheticsTest) HasName() bool { + if s != nil && s.Name != nil { + return true + } + + return false +} + +// SetName allocates a new s.Name and returns the pointer to it. +func (s *SyntheticsTest) SetName(v string) { + s.Name = &v +} + +// GetOptions returns the Options field if non-nil, zero value otherwise. +func (s *SyntheticsTest) GetOptions() SyntheticsOptions { + if s == nil || s.Options == nil { + return SyntheticsOptions{} + } + return *s.Options +} + +// GetOptionsOk returns a tuple with the Options field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsTest) GetOptionsOk() (SyntheticsOptions, bool) { + if s == nil || s.Options == nil { + return SyntheticsOptions{}, false + } + return *s.Options, true +} + +// HasOptions returns a boolean if a field has been set. +func (s *SyntheticsTest) HasOptions() bool { + if s != nil && s.Options != nil { + return true + } + + return false +} + +// SetOptions allocates a new s.Options and returns the pointer to it. +func (s *SyntheticsTest) SetOptions(v SyntheticsOptions) { + s.Options = &v +} + +// GetPublicId returns the PublicId field if non-nil, zero value otherwise. +func (s *SyntheticsTest) GetPublicId() string { + if s == nil || s.PublicId == nil { + return "" + } + return *s.PublicId +} + +// GetPublicIdOk returns a tuple with the PublicId field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsTest) GetPublicIdOk() (string, bool) { + if s == nil || s.PublicId == nil { + return "", false + } + return *s.PublicId, true +} + +// HasPublicId returns a boolean if a field has been set. +func (s *SyntheticsTest) HasPublicId() bool { + if s != nil && s.PublicId != nil { + return true + } + + return false +} + +// SetPublicId allocates a new s.PublicId and returns the pointer to it. +func (s *SyntheticsTest) SetPublicId(v string) { + s.PublicId = &v +} + +// GetStatus returns the Status field if non-nil, zero value otherwise. +func (s *SyntheticsTest) GetStatus() string { + if s == nil || s.Status == nil { + return "" + } + return *s.Status +} + +// GetStatusOk returns a tuple with the Status field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsTest) GetStatusOk() (string, bool) { + if s == nil || s.Status == nil { + return "", false + } + return *s.Status, true +} + +// HasStatus returns a boolean if a field has been set. +func (s *SyntheticsTest) HasStatus() bool { + if s != nil && s.Status != nil { + return true + } + + return false +} + +// SetStatus allocates a new s.Status and returns the pointer to it. +func (s *SyntheticsTest) SetStatus(v string) { + s.Status = &v +} + +// GetType returns the Type field if non-nil, zero value otherwise. +func (s *SyntheticsTest) GetType() string { + if s == nil || s.Type == nil { + return "" + } + return *s.Type +} + +// GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsTest) GetTypeOk() (string, bool) { + if s == nil || s.Type == nil { + return "", false + } + return *s.Type, true +} + +// HasType returns a boolean if a field has been set. +func (s *SyntheticsTest) HasType() bool { + if s != nil && s.Type != nil { + return true + } + + return false +} + +// SetType allocates a new s.Type and returns the pointer to it. +func (s *SyntheticsTest) SetType(v string) { + s.Type = &v +} + +// GetEmail returns the Email field if non-nil, zero value otherwise. +func (s *SyntheticsUser) GetEmail() string { + if s == nil || s.Email == nil { + return "" + } + return *s.Email +} + +// GetEmailOk returns a tuple with the Email field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsUser) GetEmailOk() (string, bool) { + if s == nil || s.Email == nil { + return "", false + } + return *s.Email, true +} + +// HasEmail returns a boolean if a field has been set. +func (s *SyntheticsUser) HasEmail() bool { + if s != nil && s.Email != nil { + return true + } + + return false +} + +// SetEmail allocates a new s.Email and returns the pointer to it. +func (s *SyntheticsUser) SetEmail(v string) { + s.Email = &v +} + +// GetHandle returns the Handle field if non-nil, zero value otherwise. +func (s *SyntheticsUser) GetHandle() string { + if s == nil || s.Handle == nil { + return "" + } + return *s.Handle +} + +// GetHandleOk returns a tuple with the Handle field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsUser) GetHandleOk() (string, bool) { + if s == nil || s.Handle == nil { + return "", false + } + return *s.Handle, true +} + +// HasHandle returns a boolean if a field has been set. +func (s *SyntheticsUser) HasHandle() bool { + if s != nil && s.Handle != nil { + return true + } + + return false +} + +// SetHandle allocates a new s.Handle and returns the pointer to it. +func (s *SyntheticsUser) SetHandle(v string) { + s.Handle = &v +} + +// GetId returns the Id field if non-nil, zero value otherwise. +func (s *SyntheticsUser) GetId() int { + if s == nil || s.Id == nil { + return 0 + } + return *s.Id +} + +// GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsUser) GetIdOk() (int, bool) { + if s == nil || s.Id == nil { + return 0, false + } + return *s.Id, true +} + +// HasId returns a boolean if a field has been set. +func (s *SyntheticsUser) HasId() bool { + if s != nil && s.Id != nil { + return true + } + + return false +} + +// SetId allocates a new s.Id and returns the pointer to it. +func (s *SyntheticsUser) SetId(v int) { + s.Id = &v +} + +// GetName returns the Name field if non-nil, zero value otherwise. +func (s *SyntheticsUser) GetName() string { + if s == nil || s.Name == nil { + return "" + } + return *s.Name +} + +// GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (s *SyntheticsUser) GetNameOk() (string, bool) { + if s == nil || s.Name == nil { + return "", false + } + return *s.Name, true +} + +// HasName returns a boolean if a field has been set. +func (s *SyntheticsUser) HasName() bool { + if s != nil && s.Name != nil { + return true + } + + return false +} + +// SetName allocates a new s.Name and returns the pointer to it. +func (s *SyntheticsUser) SetName(v string) { + s.Name = &v +} + // GetDefault returns the Default field if non-nil, zero value otherwise. func (t *TemplateVariable) GetDefault() string { if t == nil || t.Default == nil { @@ -8755,6 +10026,37 @@ func (t *Time) SetLiveSpan(v string) { t.LiveSpan = &v } +// GetNewStatus returns the NewStatus field if non-nil, zero value otherwise. +func (t *ToggleStatus) GetNewStatus() string { + if t == nil || t.NewStatus == nil { + return "" + } + return *t.NewStatus +} + +// GetNewStatusOk returns a tuple with the NewStatus field if it's non-nil, zero value otherwise +// and a boolean to check if the value has been set. +func (t *ToggleStatus) GetNewStatusOk() (string, bool) { + if t == nil || t.NewStatus == nil { + return "", false + } + return *t.NewStatus, true +} + +// HasNewStatus returns a boolean if a field has been set. +func (t *ToggleStatus) HasNewStatus() bool { + if t != nil && t.NewStatus != nil { + return true + } + + return false +} + +// SetNewStatus allocates a new t.NewStatus and returns the pointer to it. +func (t *ToggleStatus) SetNewStatus(v string) { + t.NewStatus = &v +} + // GetFromTs returns the FromTs field if non-nil, zero value otherwise. func (t *TriggeringValue) GetFromTs() int { if t == nil || t.FromTs == nil { diff --git a/vendor/github.com/zorkian/go-datadog-api/events.go b/vendor/github.com/zorkian/go-datadog-api/events.go index 0aeedef16f..47e3ebfc5a 100644 --- a/vendor/github.com/zorkian/go-datadog-api/events.go +++ b/vendor/github.com/zorkian/go-datadog-api/events.go @@ -60,7 +60,7 @@ func (client *Client) GetEvent(id int) (*Event, error) { return out.Event, nil } -// QueryEvents returns a slice of events from the query stream. +// GetEvents returns a slice of events from the query stream. func (client *Client) GetEvents(start, end int, priority, sources, tags string) ([]Event, error) { // Since this is a GET request, we need to build a query string. diff --git a/vendor/github.com/zorkian/go-datadog-api/helpers.go b/vendor/github.com/zorkian/go-datadog-api/helpers.go index e25d51628c..f57d413b9b 100644 --- a/vendor/github.com/zorkian/go-datadog-api/helpers.go +++ b/vendor/github.com/zorkian/go-datadog-api/helpers.go @@ -28,7 +28,7 @@ func GetBool(v *bool) (bool, bool) { // to store v and returns a pointer to it. func Int(v int) *int { return &v } -// GetInt is a helper routine that returns a boolean representing +// GetIntOk is a helper routine that returns a boolean representing // if a value was set, and if so, dereferences the pointer to it. func GetIntOk(v *int) (int, bool) { if v != nil { @@ -42,7 +42,7 @@ func GetIntOk(v *int) (int, bool) { // to store v and returns a pointer to it. func String(v string) *string { return &v } -// GetString is a helper routine that returns a boolean representing +// GetStringOk is a helper routine that returns a boolean representing // if a value was set, and if so, dereferences the pointer to it. func GetStringOk(v *string) (string, bool) { if v != nil { @@ -56,7 +56,7 @@ func GetStringOk(v *string) (string, bool) { // to store v and returns a pointer to it. func JsonNumber(v json.Number) *json.Number { return &v } -// GetJsonNumber is a helper routine that returns a boolean representing +// GetJsonNumberOk is a helper routine that returns a boolean representing // if a value was set, and if so, dereferences the pointer to it. func GetJsonNumberOk(v *json.Number) (json.Number, bool) { if v != nil { diff --git a/vendor/github.com/zorkian/go-datadog-api/monitors.go b/vendor/github.com/zorkian/go-datadog-api/monitors.go index a30e41caaa..435f911d38 100644 --- a/vendor/github.com/zorkian/go-datadog-api/monitors.go +++ b/vendor/github.com/zorkian/go-datadog-api/monitors.go @@ -140,7 +140,7 @@ func (client *Client) GetMonitor(id int) (*Monitor, error) { return &out, nil } -// GetMonitor retrieves monitors by name +// GetMonitorsByName retrieves monitors by name func (self *Client) GetMonitorsByName(name string) ([]Monitor, error) { var out reqMonitors query, err := url.ParseQuery(fmt.Sprintf("name=%v", name)) @@ -155,7 +155,7 @@ func (self *Client) GetMonitorsByName(name string) ([]Monitor, error) { return out.Monitors, nil } -// GetMonitor retrieves monitors by a slice of tags +// GetMonitorsByTags retrieves monitors by a slice of tags func (self *Client) GetMonitorsByTags(tags []string) ([]Monitor, error) { var out reqMonitors query, err := url.ParseQuery(fmt.Sprintf("monitor_tags=%v", strings.Join(tags, ","))) diff --git a/vendor/github.com/zorkian/go-datadog-api/synthetics.go b/vendor/github.com/zorkian/go-datadog-api/synthetics.go new file mode 100644 index 0000000000..e0eacc8122 --- /dev/null +++ b/vendor/github.com/zorkian/go-datadog-api/synthetics.go @@ -0,0 +1,197 @@ +package datadog + +import ( + "fmt" + "net/url" +) + +// SyntheticsTest represents a synthetics test, either api or browser +type SyntheticsTest struct { + PublicId *string `json:"public_id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Tags []string `json:"tags"` + CreatedAt *string `json:"created_at,omitempty"` + ModifiedAt *string `json:"modified_at,omitempty"` + DeletedAt *string `json:"deleted_at,omitempty"` + Config *SyntheticsConfig `json:"config,omitempty"` + Message *string `json:"message,omitempty"` + Options *SyntheticsOptions `json:"options,omitempty"` + Locations []string `json:"locations,omitempty"` + CreatedBy *SyntheticsUser `json:"created_by,omitempty"` + ModifiedBy *SyntheticsUser `json:"modified_by,omitempty"` + Status *string `json:"status,omitempty"` + MonitorStatus *string `json:"monitor_status,omitempty"` +} + +type SyntheticsConfig struct { + Request *SyntheticsRequest `json:"request,omitempty"` + Assertions []SyntheticsAssertion `json:"assertions,omitempty"` + Variables []interface{} `json:"variables,omitempty"` +} + +type SyntheticsRequest struct { + Url *string `json:"url,omitempty"` + Method *string `json:"method,omitempty"` + Timeout *int `json:"timeout,omitempty"` + Headers map[string]string `json:"headers,omitempty"` + Body *string `json:"body,omitempty"` +} + +type SyntheticsAssertion struct { + Operator *string `json:"operator,omitempty"` + Property *string `json:"property,omitempty"` + Type *string `json:"type,omitempty"` + // sometimes target is string ( like "text/html; charset=UTF-8" for header content-type ) + // and sometimes target is int ( like 1200 for responseTime, 200 for statusCode ) + Target interface{} `json:"target,omitempty"` +} + +type SyntheticsOptions struct { + TickEvery *int `json:"tick_every,omitempty"` + FollowRedirects *bool `json:"follow_redirects,omitempty"` + MinFailureDuration *int `json:"min_failure_duration,omitempty"` + MinLocationFailed *int `json:"min_location_failed,omitempty"` + DeviceIds []string `json:"device_ids,omitempty"` +} + +type SyntheticsUser struct { + Id *int `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Email *string `json:"email,omitempty"` + Handle *string `json:"handle,omitempty"` +} + +type SyntheticsDevice struct { + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Height *int `json:"height,omitempty"` + Width *int `json:"width,omitempty"` + IsLandscape *bool `json:"isLandscape,omitempty"` + IsMobile *bool `json:"isMobile,omitempty"` + UserAgent *string `json:"userAgent,omitempty"` +} + +type SyntheticsLocation struct { + Id *int `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + Region *string `json:"region,omitempty"` + IsLandscape *bool `json:"is_active,omitempty"` +} + +type ToggleStatus struct { + NewStatus *string `json:"new_status,omitempty"` +} + +// GetSyntheticsTests get all tests of type API +func (client *Client) GetSyntheticsTests() ([]SyntheticsTest, error) { + var out struct { + SyntheticsTests []SyntheticsTest `json:"tests,omitempty"` + } + if err := client.doJsonRequest("GET", "/v1/synthetics/tests", nil, &out); err != nil { + return nil, err + } + return out.SyntheticsTests, nil +} + +// GetSyntheticsTestsByType get all tests by type (e.g. api or browser) +func (client *Client) GetSyntheticsTestsByType(testType string) ([]SyntheticsTest, error) { + var out struct { + SyntheticsTests []SyntheticsTest `json:"tests,omitempty"` + } + query, err := url.ParseQuery(fmt.Sprintf("type=%v", testType)) + if err != nil { + return nil, err + } + if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/synthetics/tests?%v", query.Encode()), nil, &out); err != nil { + return nil, err + } + return out.SyntheticsTests, nil +} + +// GetSyntheticsTest get test by public id +func (client *Client) GetSyntheticsTest(publicId string) (*SyntheticsTest, error) { + var out SyntheticsTest + if err := client.doJsonRequest("GET", "/v1/synthetics/tests/"+publicId, nil, &out); err != nil { + return nil, err + } + return &out, nil +} + +// CreateSyntheticsTest creates a test +func (client *Client) CreateSyntheticsTest(syntheticsTest *SyntheticsTest) (*SyntheticsTest, error) { + var out SyntheticsTest + if err := client.doJsonRequest("POST", "/v1/synthetics/tests", syntheticsTest, &out); err != nil { + return nil, err + } + return &out, nil +} + +// UpdateSyntheticsTest updates a test +func (client *Client) UpdateSyntheticsTest(publicId string, syntheticsTest *SyntheticsTest) (*SyntheticsTest, error) { + var out SyntheticsTest + if err := client.doJsonRequest("PUT", fmt.Sprintf("/v1/synthetics/tests/%s", publicId), syntheticsTest, &out); err != nil { + return nil, err + } + return &out, nil +} + +// PauseSyntheticsTest set a test status to live +func (client *Client) PauseSyntheticsTest(publicId string) (*bool, error) { + payload := ToggleStatus{NewStatus: String("paused")} + out := Bool(false) + if err := client.doJsonRequest("PUT", fmt.Sprintf("/v1/synthetics/tests/%s/status", publicId), &payload, &out); err != nil { + return nil, err + } + return out, nil +} + +// ResumeSyntheticsTest set a test status to live +func (client *Client) ResumeSyntheticsTest(publicId string) (*bool, error) { + payload := ToggleStatus{NewStatus: String("live")} + out := Bool(false) + if err := client.doJsonRequest("PUT", fmt.Sprintf("/v1/synthetics/tests/%s/status", publicId), &payload, &out); err != nil { + return nil, err + } + return out, nil +} + +// string array of public_id +type DeleteSyntheticsTestsPayload struct { + PublicIds []string `json:"public_ids,omitempty"` +} + +// DeleteSyntheticsTests deletes tests +func (client *Client) DeleteSyntheticsTests(publicIds []string) error { + req := DeleteSyntheticsTestsPayload{ + PublicIds: publicIds, + } + if err := client.doJsonRequest("POST", "/v1/synthetics/tests/delete", req, nil); err != nil { + return err + } + return nil +} + +// GetSyntheticsLocations get all test locations +func (client *Client) GetSyntheticsLocations() ([]SyntheticsLocation, error) { + var out struct { + Locations []SyntheticsLocation `json:"locations,omitempty"` + } + if err := client.doJsonRequest("GET", "/v1/synthetics/locations", nil, &out); err != nil { + return nil, err + } + return out.Locations, nil +} + +// GetSyntheticsBrowserDevices get all test devices (for browser) +func (client *Client) GetSyntheticsBrowserDevices() ([]SyntheticsDevice, error) { + var out struct { + Devices []SyntheticsDevice `json:"devices,omitempty"` + } + + if err := client.doJsonRequest("GET", "/v1/synthetics/browser/devices", nil, &out); err != nil { + return nil, err + } + return out.Devices, nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 6f95a705c4..b2b316b7ea 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -103,6 +103,7 @@ github.com/hashicorp/hil/scanner github.com/hashicorp/logutils # github.com/hashicorp/terraform v0.11.12-beta1.0.20190227065421-fc531f54a878 github.com/hashicorp/terraform/plugin +github.com/hashicorp/terraform/helper/logging github.com/hashicorp/terraform/helper/schema github.com/hashicorp/terraform/helper/validation github.com/hashicorp/terraform/terraform @@ -126,7 +127,6 @@ github.com/hashicorp/terraform/registry/regsrc github.com/hashicorp/terraform/registry/response github.com/hashicorp/terraform/svchost/disco github.com/hashicorp/terraform/helper/config -github.com/hashicorp/terraform/helper/logging github.com/hashicorp/terraform/svchost github.com/hashicorp/terraform/svchost/auth # github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb @@ -177,7 +177,7 @@ github.com/zclconf/go-cty/cty/function/stdlib github.com/zclconf/go-cty/cty/set github.com/zclconf/go-cty/cty/gocty github.com/zclconf/go-cty/cty/json -# github.com/zorkian/go-datadog-api v2.19.0+incompatible +# github.com/zorkian/go-datadog-api v2.19.1-0.20190415084127-efa96fedb363+incompatible github.com/zorkian/go-datadog-api # golang.org/x/crypto v0.0.0-20180816225734-aabede6cba87 golang.org/x/crypto/openpgp diff --git a/website/docs/r/synthetics.html.markdown b/website/docs/r/synthetics.html.markdown new file mode 100644 index 0000000000..4201028325 --- /dev/null +++ b/website/docs/r/synthetics.html.markdown @@ -0,0 +1,109 @@ +--- +layout: "datadog" +page_title: "Datadog: datadog_synthetics_test" +sidebar_current: "docs-datadog-resource-synthetics_test" +description: |- + Provides a Datadog synthetics resource. This can be used to create and manage synthetics. +--- + +# datadog_synthetics_test + +Provides a Datadog synthetics test resource. This can be used to create and manage Datadog synthetics test. + +## Example Usage + +```hcl +# Create a new Datadog Synthetics API test on https://www.example.org +resource "datadog_synthetics_test" "foo" { + type = "api" + request { + method = "GET" + url = "https://www.example.org" + } + request_headers { + "Content-Type" = "application/json" + "Authentication" = "Token: 1234566789" + } + assertions = [ + { + type = "statusCode" + operator = "is" + target = "200" + } + ] + locations = [ "aws:eu-central-1" ] + options { + tick_every = 900 + } + name = "An API test on example.org" + message = "Notify @pagerduty" + tags = ["foo:bar", "foo", "env:test"] + + status = "live" +} + +# Create a new Datadog Synthetics Browser test starting on https://www.example.org +resource "datadog_synthetics_test" "bar" { + type = "browser" + + request { + method = "GET" + url = "https://app.datadoghq.com" + } + + device_ids = ["laptop_large"] + locations = ["aws:eu-central-1"] + + options { + tick_every = 3600 + } + + name = "A Browser test on example.org" + message = "Notify @qa" + tags = [] + + status = "paused" +} +``` + +## Argument Reference + +The following arguments are supported: + +- `type` - (Required) Synthetics test type (api or browser) +- `name` - (Required) Name of Datadog synthetics test +- `message` - (Required) A message to include with notifications for this synthetics test. + Email notifications can be sent to specific users by using the same '@username' notation as events. +- `tags` - (Required) A list of tags to associate with your synthetics test. This can help you categorize and filter tests in the manage synthetics page of the UI. +- `request` - (Required) + - `method` - (Required) DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT (noop if type=browser) + - `url` - (Required) Any url + - `timeout` - (Optional) For typ=api, any value between 0 and 60. No-op for type=browser +- `request_headers` - (Optional) Header name and value map +- `assertions` - (Required) Array of 1 to 10 items, only some combinations of type/operator are valid (please refer to Datadog documentation) + - `type` - (Required) body, header, responseTime, statusCode + - `operator` - (Required) "contains", "doesNotContain", "is", "isNot", "matches", "doesNotMatch", "validates" + - `target` - (Required) Expected string + - `property` - (Optional) +- `options` - (Required) + - `tick_every` - (Required) 900, 1800, 3600, 21600, 43200, 86400, 604800 plus 60 if type=api or 300 if type=browser + - `follow_redirects` - (Optional) true or false + - `min_failure_duration` - (Optional) Grace period during which a synthetics test is allowed to fail before sending notifications + - `min_location_failed` - (Optional) Threshold below which a synthetics test is allowed to fail before sending notifications +- `locations` - (Required) Please refer to Datadog documentation for available locations (e.g. "aws:eu-central-1") +- `device_ids` - (Optional) "laptop_large", "tablet" or "mobile_small" (only available if type=browser) +- `status` - (Required) "live", "paused" + +## Attributes Reference + +The following attributes are exported: + +- `public_id` - ID of the Datadog synthetics test + +## Import + +Synthetics tests can be imported using their public string ID, e.g. + +``` +$ terraform import datadog_synthetics_test.fizz abc-123-xyz +```