dist: trusty
-sudo: false
+sudo: required
+services:
+- docker
language: go
go:
- 1.8.1
- make test
- make vendor-status
- make vet
+- make website-test
branches:
only:
## 0.1.1 (Unreleased)
+
+IMPROVEMENTS:
+
+* `statuscake_test` - Add support for all support library options including basic auth, status codes, custom headers and more. [GH-11]
+
+
+BUG FIXES:
+
+* Fix handling of `contact_id` [GH-11]
+
+
## 0.1.0 (June 21, 2017)
NOTES:
TEST?=$$(go list ./... |grep -v 'vendor')
GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor)
+WEBSITE_REPO=github.com/hashicorp/terraform-website
+PKG_NAME=statuscake
default: build
test-compile:
@if [ "$(TEST)" = "./..." ]; then \
echo "ERROR: Set TEST to a specific package. For example,"; \
- echo " make test-compile TEST=./aws"; \
+ echo " make test-compile TEST=./$(PKG_NAME)"; \
exit 1; \
fi
go test -c $(TEST) $(TESTARGS)
-.PHONY: build test testacc vet fmt fmtcheck errcheck vendor-status test-compile
+website:
+ifeq (,$(wildcard $(GOPATH)/src/$(WEBSITE_REPO)))
+ echo "$(WEBSITE_REPO) not found in your GOPATH (necessary for layouts and assets), get-ting..."
+ git clone https://$(WEBSITE_REPO) $(GOPATH)/src/$(WEBSITE_REPO)
+endif
+ @$(MAKE) -C $(GOPATH)/src/$(WEBSITE_REPO) website-provider PROVIDER_PATH=$(shell pwd) PROVIDER_NAME=$(PKG_NAME)
+
+website-test:
+ifeq (,$(wildcard $(GOPATH)/src/$(WEBSITE_REPO)))
+ echo "$(WEBSITE_REPO) not found in your GOPATH (necessary for layouts and assets), get-ting..."
+ git clone https://$(WEBSITE_REPO) $(GOPATH)/src/$(WEBSITE_REPO)
+endif
+ @$(MAKE) -C $(GOPATH)/src/$(WEBSITE_REPO) website-provider-test PROVIDER_PATH=$(shell pwd) PROVIDER_NAME=$(PKG_NAME)
+
+.PHONY: build test testacc vet fmt fmtcheck errcheck vendor-status test-compile website website-test
Building The Provider
---------------------
-Clone repository to: `$GOPATH/src/github.com/hashicorp/terraform-provider-$PROVIDER_NAME`
+Clone repository to: `$GOPATH/src/github.com/terraform-providers/terraform-provider-statuscake`
```sh
-$ mkdir -p $GOPATH/src/github.com/hashicorp; cd $GOPATH/src/github.com/hashicorp
-$ git clone git@github.com:hashicorp/terraform-provider-$PROVIDER_NAME
+$ mkdir -p $GOPATH/src/github.com/terraform-providers; cd $GOPATH/src/github.com/terraform-providers
+$ git clone git@github.com:terraform-providers/terraform-provider-statuscake
```
Enter the provider directory and build the provider
```sh
-$ cd $GOPATH/src/github.com/hashicorp/terraform-provider-$PROVIDER_NAME
+$ cd $GOPATH/src/github.com/terraform-providers/terraform-provider-statuscake
$ make build
```
```sh
$ make bin
...
-$ $GOPATH/bin/terraform-provider-$PROVIDER_NAME
+$ $GOPATH/bin/terraform-provider-statuscake
...
```
"github.com/hashicorp/terraform/helper/schema"
)
+func castSetToSliceStrings(configured []interface{}) []string {
+ res := make([]string, len(configured))
+
+ for i, element := range configured {
+ res[i] = element.(string)
+ }
+ return res
+}
+
+// Special handling for node_locations since statuscake will return `[""]` for the empty case
+func considerEmptyStringAsEmptyArray(in []string) []string {
+ if len(in) == 1 && in[0] == "" {
+ return []string{}
+ } else {
+ return in
+ }
+}
+
func resourceStatusCakeTest() *schema.Resource {
return &schema.Resource{
Create: CreateTest,
Optional: true,
Default: 5,
},
+ "custom_header": {
+ Type: schema.TypeString,
+ Optional: true,
+ },
+
+ "user_agent": {
+ Type: schema.TypeString,
+ Optional: true,
+ },
+
+ "status": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+
+ "uptime": {
+ Type: schema.TypeFloat,
+ Computed: true,
+ },
+
+ "node_locations": {
+ Type: schema.TypeSet,
+ Elem: &schema.Schema{Type: schema.TypeString},
+ Optional: true,
+ Set: schema.HashString,
+ },
+
+ "ping_url": {
+ Type: schema.TypeString,
+ Optional: true,
+ },
+
+ "basic_user": {
+ Type: schema.TypeString,
+ Optional: true,
+ },
+
+ "basic_pass": {
+ Type: schema.TypeString,
+ Optional: true,
+ Sensitive: true,
+ },
+
+ "public": {
+ Type: schema.TypeInt,
+ Optional: true,
+ },
+
+ "logo_image": {
+ Type: schema.TypeString,
+ Optional: true,
+ },
+
+ "branding": {
+ Type: schema.TypeInt,
+ Optional: true,
+ },
+
+ "website_host": {
+ Type: schema.TypeString,
+ Optional: true,
+ },
+
+ "virus": {
+ Type: schema.TypeInt,
+ Optional: true,
+ },
+
+ "find_string": {
+ Type: schema.TypeString,
+ Optional: true,
+ },
+
+ "do_not_find": {
+ Type: schema.TypeBool,
+ Optional: true,
+ },
+
+ "real_browser": {
+ Type: schema.TypeInt,
+ Optional: true,
+ },
+
+ "test_tags": {
+ Type: schema.TypeString,
+ Optional: true,
+ },
+
+ "status_codes": {
+ Type: schema.TypeString,
+ Optional: true,
+ },
+
+ "use_jar": {
+ Type: schema.TypeInt,
+ Optional: true,
+ },
+
+ "post_raw": {
+ Type: schema.TypeString,
+ Optional: true,
+ },
+
+ "final_endpoint": {
+ Type: schema.TypeString,
+ Optional: true,
+ },
+
+ "follow_redirect": {
+ Type: schema.TypeBool,
+ Optional: true,
+ },
},
}
}
client := meta.(*statuscake.Client)
newTest := &statuscake.Test{
- WebsiteName: d.Get("website_name").(string),
- WebsiteURL: d.Get("website_url").(string),
- CheckRate: d.Get("check_rate").(int),
- TestType: d.Get("test_type").(string),
- Paused: d.Get("paused").(bool),
- Timeout: d.Get("timeout").(int),
- ContactID: d.Get("contact_id").(int),
- Confirmation: d.Get("confirmations").(int),
- Port: d.Get("port").(int),
- TriggerRate: d.Get("trigger_rate").(int),
+ WebsiteName: d.Get("website_name").(string),
+ WebsiteURL: d.Get("website_url").(string),
+ CheckRate: d.Get("check_rate").(int),
+ TestType: d.Get("test_type").(string),
+ Paused: d.Get("paused").(bool),
+ Timeout: d.Get("timeout").(int),
+ ContactID: d.Get("contact_id").(int),
+ Confirmation: d.Get("confirmations").(int),
+ Port: d.Get("port").(int),
+ TriggerRate: d.Get("trigger_rate").(int),
+ CustomHeader: d.Get("custom_header").(string),
+ UserAgent: d.Get("user_agent").(string),
+ Status: d.Get("status").(string),
+ Uptime: d.Get("uptime").(float64),
+ NodeLocations: castSetToSliceStrings(d.Get("node_locations").(*schema.Set).List()),
+ PingURL: d.Get("ping_url").(string),
+ BasicUser: d.Get("basic_user").(string),
+ BasicPass: d.Get("basic_pass").(string),
+ Public: d.Get("public").(int),
+ LogoImage: d.Get("logo_image").(string),
+ Branding: d.Get("branding").(int),
+ WebsiteHost: d.Get("website_host").(string),
+ Virus: d.Get("virus").(int),
+ FindString: d.Get("find_string").(string),
+ DoNotFind: d.Get("do_not_find").(bool),
+ RealBrowser: d.Get("real_browser").(int),
+ TestTags: d.Get("test_tags").(string),
+ StatusCodes: d.Get("status_codes").(string),
+ UseJar: d.Get("use_jar").(int),
+ PostRaw: d.Get("post_raw").(string),
+ FinalEndpoint: d.Get("final_endpoint").(string),
+ FollowRedirect: d.Get("follow_redirect").(bool),
}
log.Printf("[DEBUG] Creating new StatusCake Test: %s", d.Get("website_name").(string))
}
d.Set("test_id", fmt.Sprintf("%d", response.TestID))
+ d.Set("status", response.Status)
+ d.Set("uptime", fmt.Sprintf("%.3f", response.Uptime))
d.SetId(fmt.Sprintf("%d", response.TestID))
return ReadTest(d, meta)
d.Set("confirmations", testResp.Confirmation)
d.Set("port", testResp.Port)
d.Set("trigger_rate", testResp.TriggerRate)
+ d.Set("custom_header", testResp.CustomHeader)
+ d.Set("status", testResp.Status)
+ d.Set("uptime", testResp.Uptime)
+ if err := d.Set("node_locations", considerEmptyStringAsEmptyArray(testResp.NodeLocations)); err != nil {
+ return fmt.Errorf("[WARN] Error setting node locations: %s", err)
+ }
+ d.Set("logo_image", testResp.LogoImage)
+ // Even after WebsiteHost is set, the API returns ""
+ // API docs aren't clear on usage will only override state if we get a non-empty value back
+ if testResp.WebsiteHost != "" {
+ d.Set("website_host", testResp.WebsiteHost)
+ }
+ d.Set("find_string", testResp.FindString)
+ d.Set("do_not_find", testResp.DoNotFind)
+ d.Set("status_codes", testResp.StatusCodes)
+ d.Set("use_jar", testResp.UseJar)
+ d.Set("post_raw", testResp.PostRaw)
+ d.Set("final_endpoint", testResp.FinalEndpoint)
+ d.Set("follow_redirect", testResp.FollowRedirect)
return nil
}
if v, ok := d.GetOk("timeout"); ok {
test.Timeout = v.(int)
}
- if v, ok := d.GetOk("contact_id"); ok {
- test.ContactID = v.(int)
- }
if v, ok := d.GetOk("confirmations"); ok {
test.Confirmation = v.(int)
}
if v, ok := d.GetOk("trigger_rate"); ok {
test.TriggerRate = v.(int)
}
-
- defaultStatusCodes := "204, 205, 206, 303, 400, 401, 403, 404, 405, 406, " +
- "408, 410, 413, 444, 429, 494, 495, 496, 499, 500, 501, 502, 503, " +
- "504, 505, 506, 507, 508, 509, 510, 511, 521, 522, 523, 524, 520, " +
- "598, 599"
-
- test.StatusCodes = defaultStatusCodes
+ if v, ok := d.GetOk("custom_header"); ok {
+ test.CustomHeader = v.(string)
+ }
+ if v, ok := d.GetOk("user_agent"); ok {
+ test.UserAgent = v.(string)
+ }
+ if v, ok := d.GetOk("node_locations"); ok {
+ test.NodeLocations = castSetToSliceStrings(v.(*schema.Set).List())
+ }
+ if v, ok := d.GetOk("ping_url"); ok {
+ test.PingURL = v.(string)
+ }
+ if v, ok := d.GetOk("basic_user"); ok {
+ test.BasicUser = v.(string)
+ }
+ if v, ok := d.GetOk("basic_pass"); ok {
+ test.BasicPass = v.(string)
+ }
+ if v, ok := d.GetOk("public"); ok {
+ test.Public = v.(int)
+ }
+ if v, ok := d.GetOk("logo_image"); ok {
+ test.LogoImage = v.(string)
+ }
+ if v, ok := d.GetOk("branding"); ok {
+ test.Branding = v.(int)
+ }
+ if v, ok := d.GetOk("website_host"); ok {
+ test.WebsiteHost = v.(string)
+ }
+ if v, ok := d.GetOk("virus"); ok {
+ test.Virus = v.(int)
+ }
+ if v, ok := d.GetOk("find_string"); ok {
+ test.FindString = v.(string)
+ }
+ if v, ok := d.GetOk("do_not_find"); ok {
+ test.DoNotFind = v.(bool)
+ }
+ if v, ok := d.GetOk("real_browser"); ok {
+ test.RealBrowser = v.(int)
+ }
+ if v, ok := d.GetOk("test_tags"); ok {
+ test.TestTags = v.(string)
+ }
+ if v, ok := d.GetOk("status_codes"); ok {
+ test.StatusCodes = v.(string)
+ }
+ if v, ok := d.GetOk("use_jar"); ok {
+ test.UseJar = v.(int)
+ }
+ if v, ok := d.GetOk("post_raw"); ok {
+ test.PostRaw = v.(string)
+ }
+ if v, ok := d.GetOk("final_endpoint"); ok {
+ test.FinalEndpoint = v.(string)
+ }
+ if v, ok := d.GetOk("follow_redirect"); ok {
+ test.FollowRedirect = v.(bool)
+ }
return test
}
import (
"fmt"
+ "os"
"strconv"
"testing"
CheckDestroy: testAccTestCheckDestroy(&test),
Steps: []resource.TestStep{
{
- Config: testAccTestConfig_basic,
+ Config: interpolateTerraformTemplate(testAccTestConfig_basic),
Check: resource.ComposeTestCheckFunc(
testAccTestCheckExists("statuscake_test.google", &test),
testAccTestCheckAttributes("statuscake_test.google", &test),
CheckDestroy: testAccTestCheckDestroy(&test),
Steps: []resource.TestStep{
{
- Config: testAccTestConfig_tcp,
+ Config: interpolateTerraformTemplate(testAccTestConfig_tcp),
Check: resource.ComposeTestCheckFunc(
testAccTestCheckExists("statuscake_test.google", &test),
testAccTestCheckAttributes("statuscake_test.google", &test),
CheckDestroy: testAccTestCheckDestroy(&test),
Steps: []resource.TestStep{
{
- Config: testAccTestConfig_basic,
+ Config: interpolateTerraformTemplate(testAccTestConfig_basic),
Check: resource.ComposeTestCheckFunc(
testAccTestCheckExists("statuscake_test.google", &test),
),
resource.TestCheckResourceAttr("statuscake_test.google", "contact_id", "0"),
resource.TestCheckResourceAttr("statuscake_test.google", "confirmations", "0"),
resource.TestCheckResourceAttr("statuscake_test.google", "trigger_rate", "20"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "custom_header", "{ \"Content-Type\": \"application/x-www-form-urlencoded\" }"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "user_agent", "string9988"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "status", "Up"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "uptime", "0"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "node_locations.#", "3"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "ping_url", "string8410"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "basic_user", "string27052"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "basic_pass", "string5659"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "public", "0"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "logo_image", "string21087"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "branding", "25875"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "website_host", "string32368"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "virus", "1"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "find_string", "string15212"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "do_not_find", "false"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "real_browser", "1"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "test_tags", "string8191"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "status_codes", "string23065"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "use_jar", "1"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "post_raw", "string32096"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "final_endpoint", "string10781"),
+ resource.TestCheckResourceAttr("statuscake_test.google", "follow_redirect", "true"),
),
},
},
err = check(key, value, strconv.Itoa(test.Confirmation))
case "trigger_rate":
err = check(key, value, strconv.Itoa(test.TriggerRate))
+ case "custom_header":
+ err = check(key, value, test.CustomHeader)
+ case "node_locations":
+ for _, tv := range test.NodeLocations {
+ err = check(key, value, tv)
+ if err != nil {
+ return err
+ }
+ }
+ case "public":
+ err = check(key, value, strconv.Itoa(test.Public))
+ case "logo_image":
+ err = check(key, value, test.LogoImage)
+ case "find_string":
+ err = check(key, value, test.FindString)
+ case "do_not_find":
+ err = check(key, value, strconv.FormatBool(test.DoNotFind))
+ case "status_codes":
+ err = check(key, value, test.StatusCodes)
+ case "use_jar":
+ err = check(key, value, strconv.Itoa(test.UseJar))
+ case "post_raw":
+ err = check(key, value, test.PostRaw)
+ case "final_endpoint":
+ err = check(key, value, test.FinalEndpoint)
+ case "follow_redirect":
+ err = check(key, value, strconv.FormatBool(test.FollowRedirect))
}
-
if err != nil {
return err
}
}
}
+func interpolateTerraformTemplate(template string) string {
+ testContactGroupId := 43402
+
+ if v := os.Getenv("STATUSCAKE_TEST_CONTACT_GROUP_ID"); v != "" {
+ id, err := strconv.Atoi(v)
+ if err == nil {
+ testContactGroupId = id
+ }
+ }
+
+ return fmt.Sprintf(template, testContactGroupId)
+}
+
const testAccTestConfig_basic = `
resource "statuscake_test" "google" {
website_name = "google.com"
test_type = "HTTP"
check_rate = 300
timeout = 10
- contact_id = 43402
+ contact_id = %d
confirmations = 1
trigger_rate = 10
}
check_rate = 500
paused = true
trigger_rate = 20
+ custom_header = "{ \"Content-Type\": \"application/x-www-form-urlencoded\" }"
+ user_agent = "string9988"
+ node_locations = [ "string16045", "string19741", "string12122" ]
+ ping_url = "string8410"
+ basic_user = "string27052"
+ basic_pass = "string5659"
+ public = 0
+ logo_image = "string21087"
+ branding = 25875
+ website_host = "string32368"
+ virus = 1
+ find_string = "string15212"
+ do_not_find = false
+ real_browser = 1
+ test_tags = "string8191"
+ status_codes = "string23065"
+ use_jar = 1
+ post_raw = "string32096"
+ final_endpoint = "string10781"
+ follow_redirect = true
}
`
test_type = "TCP"
check_rate = 300
timeout = 10
- contact_id = 43402
+ contact_id = %d
confirmations = 1
port = 80
}
package statuscake
+import (
+ "strings"
+)
+
type autheticationErrorResponse struct {
ErrNo int
Error string
ContactID int `json:"ContactID"`
Status string `json:"Status"`
Uptime float64 `json:"Uptime"`
+ CustomHeader string `json:"CustomHeader"`
+ UserAgent string `json:"UserAgent"`
CheckRate int `json:"CheckRate"`
Timeout int `json:"Timeout"`
LogoImage string `json:"LogoImage"`
DownTimes int `json:"DownTimes,string"`
Sensitive bool `json:"Sensitive"`
TriggerRate int `json:"TriggerRate,string"`
+ UseJar int `json:"UseJar"`
+ PostRaw string `json:"PostRaw"`
+ FinalEndpoint string `json:"FinalEndpoint"`
+ FollowRedirect bool `json:"FollowRedirect"`
+ StatusCodes []string `json:"StatusCodes"`
}
func (d *detailResponse) test() *Test {
return &Test{
- TestID: d.TestID,
- TestType: d.TestType,
- Paused: d.Paused,
- WebsiteName: d.WebsiteName,
- WebsiteURL: d.URI,
- ContactID: d.ContactID,
- Status: d.Status,
- Uptime: d.Uptime,
- CheckRate: d.CheckRate,
- Timeout: d.Timeout,
- LogoImage: d.LogoImage,
- Confirmation: d.Confirmation,
- WebsiteHost: d.WebsiteHost,
- NodeLocations: d.NodeLocations,
- FindString: d.FindString,
- DoNotFind: d.DoNotFind,
- Port: d.Port,
- TriggerRate: d.TriggerRate,
+ TestID: d.TestID,
+ TestType: d.TestType,
+ Paused: d.Paused,
+ WebsiteName: d.WebsiteName,
+ WebsiteURL: d.URI,
+ CustomHeader: d.CustomHeader,
+ UserAgent: d.UserAgent,
+ ContactID: d.ContactID,
+ Status: d.Status,
+ Uptime: d.Uptime,
+ CheckRate: d.CheckRate,
+ Timeout: d.Timeout,
+ LogoImage: d.LogoImage,
+ Confirmation: d.Confirmation,
+ WebsiteHost: d.WebsiteHost,
+ NodeLocations: d.NodeLocations,
+ FindString: d.FindString,
+ DoNotFind: d.DoNotFind,
+ Port: d.Port,
+ TriggerRate: d.TriggerRate,
+ UseJar: d.UseJar,
+ PostRaw: d.PostRaw,
+ FinalEndpoint: d.FinalEndpoint,
+ FollowRedirect: d.FollowRedirect,
+ StatusCodes: strings.Join(d.StatusCodes[:], ","),
}
}
// Website name. Tags are stripped out
WebsiteName string `json:"WebsiteName" querystring:"WebsiteName"`
+ // CustomHeader. A special header that will be sent along with the HTTP tests.
+ CustomHeader string `json:"CustomHeader" querystring:"CustomHeader"`
+
+ // Use to populate the test with a custom user agent
+ UserAgent string `json:"UserAgent" queryString:"UserAgent"`
+
// Test location, either an IP (for TCP and Ping) or a fully qualified URL for other TestTypes
WebsiteURL string `json:"WebsiteURL" querystring:"WebsiteURL"`
// Comma Seperated List of StatusCodes to Trigger Error on (on Update will replace, so send full list each time)
StatusCodes string `json:"StatusCodes" querystring:"StatusCodes"`
+
+ // Set to 1 to enable the Cookie Jar. Required for some redirects.
+ UseJar int `json:"UseJar" querystring:"UseJar"`
+
+ // Raw POST data seperated by an ampersand
+ PostRaw string `json:"PostRaw" querystring:"PostRaw"`
+
+ // Use to specify the expected Final URL in the testing process
+ FinalEndpoint string `json:"FinalEndpoint" querystring:"FinalEndpoint"`
+
+ // Use to specify whether redirects should be followed
+ FollowRedirect bool `json:"FollowRedirect" querystring:"FollowRedirect"`
}
// Validate checks if the Test is valid. If it's invalid, it returns a ValidationError with all invalid fields. It returns nil otherwise.
e["TriggerRate"] = "must be between 0 and 59"
}
+ if t.PostRaw != "" && t.TestType != "HTTP" {
+ e["PostRaw"] = "must be HTTP to submit a POST request"
+ }
+
+ if t.FinalEndpoint != "" && t.TestType != "HTTP" {
+ e["FinalEndpoint"] = "must be a Valid URL"
+ }
+
+ var jsonVerifiable map[string]interface{}
+ if json.Unmarshal([]byte(t.CustomHeader), &jsonVerifiable) != nil {
+ e["CustomHeader"] = "must be provided as json string"
+ }
+
if len(e) > 0 {
return e
}
"ignore": "appengine test github.com/hashicorp/nomad/ github.com/hashicorp/terraform/backend",
"package": [
{
- "checksumSHA1": "MV5JueYPwNkLZ+KNqmDcNDhsKi4=",
+ "checksumSHA1": "6Fo7YzTT+MDviHOsqg6dNw8WrV4=",
"path": "github.com/DreamItGetIT/statuscake",
- "revision": "acc13ec021cd1e8a6ebb1d9035f513217f5c4562",
- "revisionTime": "2017-04-10T11:34:45Z"
+ "revision": "f69198f958d7326f3c110dd9be1c21abbd8a87a7",
+ "revisionTime": "2018-01-30T22:14:43Z"
},
{
"checksumSHA1": "FIL83loX9V9APvGQIjJpbxq53F0=",
* `confirmations` - (Optional) The number of confirmation servers to use in order to detect downtime. Defaults to 0.
* `port` - (Optional) The port to use when specifying a TCP test.
* `trigger_rate` - (Optional) The number of minutes to wait before sending an alert. Default is `5`.
-
+* `custom_header` - (Optional) Custom HTTP header, must be supplied as JSON.
+* `user_agent` - (Optional) Test with a custom user agent set.
+* `node_locations` - (Optional) Set test node locations, must be array of strings.
+* `ping_url` - (Optional) A URL to ping if a site goes down.
+* `basic_user` - (Optional) A Basic Auth User account to use to login
+* `basic_pass` - (Optional) If BasicUser is set then this should be the password for the BasicUser.
+* `public` - (Optional) Set 1 to enable public reporting, 0 to disable.
+* `logo_image` - (Optional) A URL to a image to use for public reporting.
+* `branding` - (Optional) Set to 0 to use branding (default) or 1 to disable public reporting branding).
+* `website_host` - (Optional) Used internally, when possible please add.
+* `virus` - (Optional) Enable virus checking or not. 1 to enable
+* `find_string` - (Optional) A string that should either be found or not found.
+* `do_not_find` - (Optional) If the above string should be found to trigger a alert. 1 = will trigger if find_string found.
+* `real_browser` - (Optional) Use 1 to TURN OFF real browser testing.
+* `test_tags` - (Optional) Tags should be seperated by a comma - no spacing between tags (this,is,a set,of,tags).
+* `status_codes` - (Optional) Comma Seperated List of StatusCodes to Trigger Error on. Defaults are "204, 205, 206, 303, 400, 401, 403, 404, 405, 406, 408, 410, 413, 444, 429, 494, 495, 496, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 521, 522, 523, 524, 520, 598, 599".
+* `use_jar` - (Optional) Set to true to enable the Cookie Jar. Required for some redirects. Default is false.
+* `post_raw` - (Optional) Use to populate the RAW POST data field on the test.
+* `final_endpoint` - (Optional) Use to specify the expected Final URL in the testing process.
+* `follow_redirect` - (Optional) Use to specify whether redirects should be followed, set to true to enable. Default is false.
## Attributes Reference