From dbde71c990295605ce351a494888c15f3d6be9a8 Mon Sep 17 00:00:00 2001 From: Jake Champlin Date: Tue, 6 Jun 2017 12:40:02 -0400 Subject: Transfer statuscake provider --- statuscake/provider.go | 40 ++++++ statuscake/provider_test.go | 38 +++++ statuscake/resource_statuscaketest.go | 216 +++++++++++++++++++++++++++++ statuscake/resource_statuscaketest_test.go | 202 +++++++++++++++++++++++++++ 4 files changed, 496 insertions(+) create mode 100644 statuscake/provider.go create mode 100644 statuscake/provider_test.go create mode 100644 statuscake/resource_statuscaketest.go create mode 100644 statuscake/resource_statuscaketest_test.go (limited to 'statuscake') diff --git a/statuscake/provider.go b/statuscake/provider.go new file mode 100644 index 0000000..abca376 --- /dev/null +++ b/statuscake/provider.go @@ -0,0 +1,40 @@ +package statuscake + +import ( + "github.com/DreamItGetIT/statuscake" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/terraform" +) + +func Provider() terraform.ResourceProvider { + return &schema.Provider{ + Schema: map[string]*schema.Schema{ + "username": &schema.Schema{ + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("STATUSCAKE_USERNAME", nil), + Description: "Username for StatusCake Account.", + }, + "apikey": &schema.Schema{ + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("STATUSCAKE_APIKEY", nil), + Description: "API Key for StatusCake", + }, + }, + + ResourcesMap: map[string]*schema.Resource{ + "statuscake_test": resourceStatusCakeTest(), + }, + + ConfigureFunc: providerConfigure, + } +} + +func providerConfigure(d *schema.ResourceData) (interface{}, error) { + auth := statuscake.Auth{ + Username: d.Get("username").(string), + Apikey: d.Get("apikey").(string), + } + return statuscake.New(auth) +} diff --git a/statuscake/provider_test.go b/statuscake/provider_test.go new file mode 100644 index 0000000..83045d0 --- /dev/null +++ b/statuscake/provider_test.go @@ -0,0 +1,38 @@ +package statuscake + +import ( + "os" + "testing" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/terraform" +) + +var testAccProviders map[string]terraform.ResourceProvider +var testAccProvider *schema.Provider + +func init() { + testAccProvider = Provider().(*schema.Provider) + testAccProviders = map[string]terraform.ResourceProvider{ + "statuscake": testAccProvider, + } +} + +func TestProvider(t *testing.T) { + if err := Provider().(*schema.Provider).InternalValidate(); err != nil { + t.Fatalf("err: %s", err) + } +} + +func TestProvider_impl(t *testing.T) { + var _ terraform.ResourceProvider = Provider() +} + +func testAccPreCheck(t *testing.T) { + if v := os.Getenv("STATUSCAKE_USERNAME"); v == "" { + t.Fatal("STATUSCAKE_USERNAME must be set for acceptance tests") + } + if v := os.Getenv("STATUSCAKE_APIKEY"); v == "" { + t.Fatal("STATUSCAKE_APIKEY must be set for acceptance tests") + } +} diff --git a/statuscake/resource_statuscaketest.go b/statuscake/resource_statuscaketest.go new file mode 100644 index 0000000..101ee83 --- /dev/null +++ b/statuscake/resource_statuscaketest.go @@ -0,0 +1,216 @@ +package statuscake + +import ( + "fmt" + "strconv" + + "log" + + "github.com/DreamItGetIT/statuscake" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceStatusCakeTest() *schema.Resource { + return &schema.Resource{ + Create: CreateTest, + Update: UpdateTest, + Delete: DeleteTest, + Read: ReadTest, + + Schema: map[string]*schema.Schema{ + "test_id": { + Type: schema.TypeString, + Computed: true, + }, + + "website_name": { + Type: schema.TypeString, + Required: true, + }, + + "website_url": { + Type: schema.TypeString, + Required: true, + }, + + "contact_id": { + Type: schema.TypeInt, + Optional: true, + }, + + "check_rate": { + Type: schema.TypeInt, + Optional: true, + Default: 300, + }, + + "test_type": { + Type: schema.TypeString, + Required: true, + }, + + "paused": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + + "timeout": { + Type: schema.TypeInt, + Optional: true, + Default: 40, + }, + + "confirmations": { + Type: schema.TypeInt, + Optional: true, + }, + + "port": { + Type: schema.TypeInt, + Optional: true, + }, + + "trigger_rate": { + Type: schema.TypeInt, + Optional: true, + Default: 5, + }, + }, + } +} + +func CreateTest(d *schema.ResourceData, meta interface{}) error { + 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), + } + + log.Printf("[DEBUG] Creating new StatusCake Test: %s", d.Get("website_name").(string)) + + response, err := client.Tests().Update(newTest) + if err != nil { + return fmt.Errorf("Error creating StatusCake Test: %s", err.Error()) + } + + d.Set("test_id", fmt.Sprintf("%d", response.TestID)) + d.SetId(fmt.Sprintf("%d", response.TestID)) + + return ReadTest(d, meta) +} + +func UpdateTest(d *schema.ResourceData, meta interface{}) error { + client := meta.(*statuscake.Client) + + params := getStatusCakeTestInput(d) + + log.Printf("[DEBUG] StatusCake Test Update for %s", d.Id()) + _, err := client.Tests().Update(params) + if err != nil { + return fmt.Errorf("Error Updating StatusCake Test: %s", err.Error()) + } + return nil +} + +func DeleteTest(d *schema.ResourceData, meta interface{}) error { + client := meta.(*statuscake.Client) + + testId, parseErr := strconv.Atoi(d.Id()) + if parseErr != nil { + return parseErr + } + log.Printf("[DEBUG] Deleting StatusCake Test: %s", d.Id()) + err := client.Tests().Delete(testId) + if err != nil { + return err + } + + return nil +} + +func ReadTest(d *schema.ResourceData, meta interface{}) error { + client := meta.(*statuscake.Client) + + testId, parseErr := strconv.Atoi(d.Id()) + if parseErr != nil { + return parseErr + } + testResp, err := client.Tests().Detail(testId) + if err != nil { + return fmt.Errorf("Error Getting StatusCake Test Details for %s: Error: %s", d.Id(), err) + } + d.Set("website_name", testResp.WebsiteName) + d.Set("website_url", testResp.WebsiteURL) + d.Set("check_rate", testResp.CheckRate) + d.Set("test_type", testResp.TestType) + d.Set("paused", testResp.Paused) + d.Set("timeout", testResp.Timeout) + d.Set("contact_id", testResp.ContactID) + d.Set("confirmations", testResp.Confirmation) + d.Set("port", testResp.Port) + d.Set("trigger_rate", testResp.TriggerRate) + + return nil +} + +func getStatusCakeTestInput(d *schema.ResourceData) *statuscake.Test { + testId, parseErr := strconv.Atoi(d.Id()) + if parseErr != nil { + log.Printf("[DEBUG] Error Parsing StatusCake TestID: %s", d.Id()) + } + test := &statuscake.Test{ + TestID: testId, + } + if v, ok := d.GetOk("website_name"); ok { + test.WebsiteName = v.(string) + } + if v, ok := d.GetOk("website_url"); ok { + test.WebsiteURL = v.(string) + } + if v, ok := d.GetOk("check_rate"); ok { + test.CheckRate = v.(int) + } + if v, ok := d.GetOk("contact_id"); ok { + test.ContactID = v.(int) + } + if v, ok := d.GetOk("test_type"); ok { + test.TestType = v.(string) + } + if v, ok := d.GetOk("paused"); ok { + test.Paused = v.(bool) + } + 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("port"); ok { + test.Port = 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 + + return test +} diff --git a/statuscake/resource_statuscaketest_test.go b/statuscake/resource_statuscaketest_test.go new file mode 100644 index 0000000..f07fcc5 --- /dev/null +++ b/statuscake/resource_statuscaketest_test.go @@ -0,0 +1,202 @@ +package statuscake + +import ( + "fmt" + "strconv" + "testing" + + "github.com/DreamItGetIT/statuscake" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccStatusCake_basic(t *testing.T) { + var test statuscake.Test + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccTestCheckDestroy(&test), + Steps: []resource.TestStep{ + { + Config: testAccTestConfig_basic, + Check: resource.ComposeTestCheckFunc( + testAccTestCheckExists("statuscake_test.google", &test), + testAccTestCheckAttributes("statuscake_test.google", &test), + ), + }, + }, + }) +} + +func TestAccStatusCake_tcp(t *testing.T) { + var test statuscake.Test + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccTestCheckDestroy(&test), + Steps: []resource.TestStep{ + { + Config: testAccTestConfig_tcp, + Check: resource.ComposeTestCheckFunc( + testAccTestCheckExists("statuscake_test.google", &test), + testAccTestCheckAttributes("statuscake_test.google", &test), + ), + }, + }, + }) +} + +func TestAccStatusCake_withUpdate(t *testing.T) { + var test statuscake.Test + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccTestCheckDestroy(&test), + Steps: []resource.TestStep{ + { + Config: testAccTestConfig_basic, + Check: resource.ComposeTestCheckFunc( + testAccTestCheckExists("statuscake_test.google", &test), + ), + }, + + { + Config: testAccTestConfig_update, + Check: resource.ComposeTestCheckFunc( + testAccTestCheckExists("statuscake_test.google", &test), + testAccTestCheckAttributes("statuscake_test.google", &test), + resource.TestCheckResourceAttr("statuscake_test.google", "check_rate", "500"), + resource.TestCheckResourceAttr("statuscake_test.google", "paused", "true"), + resource.TestCheckResourceAttr("statuscake_test.google", "timeout", "40"), + resource.TestCheckResourceAttr("statuscake_test.google", "contact_id", "0"), + resource.TestCheckResourceAttr("statuscake_test.google", "confirmations", "0"), + resource.TestCheckResourceAttr("statuscake_test.google", "trigger_rate", "20"), + ), + }, + }, + }) +} + +func testAccTestCheckExists(rn string, test *statuscake.Test) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[rn] + if !ok { + return fmt.Errorf("resource not found: %s", rn) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("TestID not set") + } + + client := testAccProvider.Meta().(*statuscake.Client) + testId, parseErr := strconv.Atoi(rs.Primary.ID) + if parseErr != nil { + return fmt.Errorf("error in statuscake test CheckExists: %s", parseErr) + } + + gotTest, err := client.Tests().Detail(testId) + if err != nil { + return fmt.Errorf("error getting test: %s", err) + } + + *test = *gotTest + + return nil + } +} + +func testAccTestCheckAttributes(rn string, test *statuscake.Test) resource.TestCheckFunc { + return func(s *terraform.State) error { + attrs := s.RootModule().Resources[rn].Primary.Attributes + + check := func(key, stateValue, testValue string) error { + if testValue != stateValue { + return fmt.Errorf("different values for %s in state (%s) and in statuscake (%s)", + key, stateValue, testValue) + } + return nil + } + + for key, value := range attrs { + var err error + + switch key { + case "website_name": + err = check(key, value, test.WebsiteName) + case "website_url": + err = check(key, value, test.WebsiteURL) + case "check_rate": + err = check(key, value, strconv.Itoa(test.CheckRate)) + case "test_type": + err = check(key, value, test.TestType) + case "paused": + err = check(key, value, strconv.FormatBool(test.Paused)) + case "timeout": + err = check(key, value, strconv.Itoa(test.Timeout)) + case "contact_id": + err = check(key, value, strconv.Itoa(test.ContactID)) + case "confirmations": + err = check(key, value, strconv.Itoa(test.Confirmation)) + case "trigger_rate": + err = check(key, value, strconv.Itoa(test.TriggerRate)) + } + + if err != nil { + return err + } + } + return nil + } +} + +func testAccTestCheckDestroy(test *statuscake.Test) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*statuscake.Client) + err := client.Tests().Delete(test.TestID) + if err == nil { + return fmt.Errorf("test still exists") + } + + return nil + } +} + +const testAccTestConfig_basic = ` +resource "statuscake_test" "google" { + website_name = "google.com" + website_url = "www.google.com" + test_type = "HTTP" + check_rate = 300 + timeout = 10 + contact_id = 43402 + confirmations = 1 + trigger_rate = 10 +} +` + +const testAccTestConfig_update = ` +resource "statuscake_test" "google" { + website_name = "google.com" + website_url = "www.google.com" + test_type = "HTTP" + check_rate = 500 + paused = true + trigger_rate = 20 +} +` + +const testAccTestConfig_tcp = ` +resource "statuscake_test" "google" { + website_name = "google.com" + website_url = "www.google.com" + test_type = "TCP" + check_rate = 300 + timeout = 10 + contact_id = 43402 + confirmations = 1 + port = 80 +} +` -- cgit v1.2.3