From 0b957cd46a2a3a209c45778da2a7e1e55a94f3c7 Mon Sep 17 00:00:00 2001 From: Alexandre Garand Date: Fri, 9 Aug 2019 11:02:14 +0200 Subject: [PATCH] add contact_group resource to the provider --- statuscake/provider.go | 3 +- statuscake/resource_statuscakecontactgroup.go | 138 +++++++++++++++ .../resource_statuscakecontactgroup_test.go | 157 ++++++++++++++++++ website/docs/index.html.markdown | 10 +- website/docs/r/contact_group.html.markdown | 47 ++++++ website/statuscake.erb | 3 + 6 files changed, 356 insertions(+), 2 deletions(-) create mode 100644 statuscake/resource_statuscakecontactgroup.go create mode 100644 statuscake/resource_statuscakecontactgroup_test.go create mode 100644 website/docs/r/contact_group.html.markdown diff --git a/statuscake/provider.go b/statuscake/provider.go index 93c691f..774444f 100644 --- a/statuscake/provider.go +++ b/statuscake/provider.go @@ -24,7 +24,8 @@ func Provider() terraform.ResourceProvider { }, ResourcesMap: map[string]*schema.Resource{ - "statuscake_test": resourceStatusCakeTest(), + "statuscake_test": resourceStatusCakeTest(), + "statuscake_contact_group": resourceStatusCakeContactGroup(), }, ConfigureFunc: providerConfigure, diff --git a/statuscake/resource_statuscakecontactgroup.go b/statuscake/resource_statuscakecontactgroup.go new file mode 100644 index 0000000..612f96e --- /dev/null +++ b/statuscake/resource_statuscakecontactgroup.go @@ -0,0 +1,138 @@ +package statuscake + +import ( + "fmt" + + "github.com/DreamItGetIT/statuscake" + "github.com/hashicorp/terraform/helper/schema" + "log" + "strconv" +) + +func resourceStatusCakeContactGroup() *schema.Resource { + return &schema.Resource{ + Create: CreateContactGroup, + Update: UpdateContactGroup, + Delete: DeleteContactGroup, + Read: ReadContactGroup, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "contact_id": { + Type: schema.TypeInt, + Computed: true, + }, + "desktop_alert": { + Type: schema.TypeString, + Optional: true, + }, + "ping_url": { + Type: schema.TypeString, + Optional: true, + }, + "group_name": { + Type: schema.TypeString, + Required: true, + }, + "pushover": { + Type: schema.TypeString, + Optional: true, + }, + "boxcar": { + Type: schema.TypeString, + Optional: true, + }, + "mobiles": { + Type: schema.TypeString, + Optional: true, + }, + "emails": { + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + }, + }, + } +} + +func CreateContactGroup(d *schema.ResourceData, meta interface{}) error { + client := meta.(*statuscake.Client) + + newContactGroup := &statuscake.ContactGroup{ + GroupName: d.Get("group_name").(string), + Emails: castSetToSliceStrings(d.Get("emails").(*schema.Set).List()), + Mobiles: d.Get("mobiles").(string), + Boxcar: d.Get("boxcar").(string), + Pushover: d.Get("pushover").(string), + DesktopAlert: d.Get("desktop_alert").(string), + PingURL: d.Get("ping_url").(string), + } + + log.Printf("[DEBUG] Creating new StatusCake Contact group: %s", d.Get("group_name").(string)) + + response, err := statuscake.NewContactGroups(client).Create(newContactGroup) + if err != nil { + return fmt.Errorf("Error creating StatusCake ContactGroup: %s", err.Error()) + } + + d.Set("mobiles", newContactGroup.Mobiles) + d.Set("boxcar", newContactGroup.Boxcar) + d.Set("pushover", newContactGroup.Pushover) + d.Set("desktop_alert", newContactGroup.DesktopAlert) + d.Set("contact_id", newContactGroup.ContactID) + d.SetId(strconv.Itoa(response.ContactID)) + + return ReadContactGroup(d, meta) +} + +func UpdateContactGroup(d *schema.ResourceData, meta interface{}) error { + client := meta.(*statuscake.Client) + + params := &statuscake.ContactGroup{ + GroupName: d.Get("group_name").(string), + Emails: castSetToSliceStrings(d.Get("emails").(*schema.Set).List()), + Mobiles: d.Get("mobiles").(string), + ContactID: d.Get("contact_id").(int), + Boxcar: d.Get("boxcar").(string), + Pushover: d.Get("pushover").(string), + DesktopAlert: d.Get("desktop_alert").(string), + PingURL: d.Get("ping_url").(string), + } + log.Printf("[DEBUG] StatusCake ContactGroup Update for %s", d.Id()) + _, err := statuscake.NewContactGroups(client).Update(params) + d.Set("mobiles", params.Mobiles) + d.Set("boxcar", params.Boxcar) + d.Set("pushover", params.Pushover) + d.Set("desktop_alert", params.DesktopAlert) + if err != nil { + return fmt.Errorf("Error Updating StatusCake ContactGroup: %s", err.Error()) + } + return ReadContactGroup(d, meta) +} + +func DeleteContactGroup(d *schema.ResourceData, meta interface{}) error { + client := meta.(*statuscake.Client) + + log.Printf("[DEBUG] Deleting StatusCake ContactGroup: %s", d.Id()) + err := statuscake.NewContactGroups(client).Delete(d.Get("contact_id").(int)) + + return err +} + +func ReadContactGroup(d *schema.ResourceData, meta interface{}) error { + client := meta.(*statuscake.Client) + + response, err := statuscake.NewContactGroups(client).Detail(d.Get("contact_id").(int)) + if err != nil { + return fmt.Errorf("Error Getting StatusCake ContactGroup Details for %s: Error: %s", d.Id(), err) + } + d.Set("group_name", response.GroupName) + d.Set("emails", response.Emails) + d.Set("contact_id", response.ContactID) + d.Set("ping_url", response.PingURL) + d.SetId(strconv.Itoa(response.ContactID)) + + return nil +} diff --git a/statuscake/resource_statuscakecontactgroup_test.go b/statuscake/resource_statuscakecontactgroup_test.go new file mode 100644 index 0000000..a409808 --- /dev/null +++ b/statuscake/resource_statuscakecontactgroup_test.go @@ -0,0 +1,157 @@ +package statuscake + +import ( + "fmt" + "github.com/DreamItGetIT/statuscake" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "strconv" + "testing" +) + +func TestAccStatusCakeContactGroup_basic(t *testing.T) { + var contactGroup statuscake.ContactGroup + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccContactGroupCheckDestroy(&contactGroup), + Steps: []resource.TestStep{ + { + Config: testAccContactGroupConfig_basic, + Check: resource.ComposeTestCheckFunc( + testAccContactGroupCheckExists("statuscake_contact_group.exemple", &contactGroup), + testAccContactGroupCheckAttributes("statuscake_contact_group.exemple", &contactGroup), + ), + }, + }, + }) +} + +func TestAccStatusCakeContactGroup_withUpdate(t *testing.T) { + var contactGroup statuscake.ContactGroup + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccContactGroupCheckDestroy(&contactGroup), + Steps: []resource.TestStep{ + { + Config: testAccContactGroupConfig_basic, + Check: resource.ComposeTestCheckFunc( + testAccContactGroupCheckExists("statuscake_contact_group.exemple", &contactGroup), + testAccContactGroupCheckAttributes("statuscake_contact_group.exemple", &contactGroup), + ), + }, + + { + Config: testAccContactGroupConfig_update, + Check: resource.ComposeTestCheckFunc( + testAccContactGroupCheckExists("statuscake_contact_group.exemple", &contactGroup), + testAccContactGroupCheckAttributes("statuscake_contact_group.exemple", &contactGroup), + resource.TestCheckResourceAttr("statuscake_contact_group.exemple", "group_name", "group"), + resource.TestCheckResourceAttr("statuscake_contact_group.exemple", "ping_url", "https"), + ), + }, + }, + }) +} + +func testAccContactGroupCheckExists(rn string, contactGroup *statuscake.ContactGroup) 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("ContactGroupID not set") + } + + client := testAccProvider.Meta().(*statuscake.Client) + contactGroupId, _ := strconv.Atoi(rs.Primary.ID) + + gotContactGroup, err := statuscake.NewContactGroups(client).Detail(contactGroupId) + if err != nil { + return fmt.Errorf("error getting ContactGroup: %s", err) + } + + *contactGroup = *gotContactGroup + + return nil + } +} + +func testAccContactGroupCheckAttributes(rn string, contactGroup *statuscake.ContactGroup) resource.TestCheckFunc { + return func(s *terraform.State) error { + attrs := s.RootModule().Resources[rn].Primary.Attributes + + check := func(key, stateValue, contactGroupValue string) error { + if contactGroupValue != stateValue { + return fmt.Errorf("different values for %s in state (%s) and in statuscake (%s)", + key, stateValue, contactGroupValue) + } + return nil + } + + for key, value := range attrs { + var err error + + switch key { + case "contact_id": + err = check(key, value, strconv.Itoa(contactGroup.ContactID)) + case "desktop_alert": + err = check(key, value, contactGroup.DesktopAlert) + case "ping_url": + err = check(key, value, contactGroup.PingURL) + case "group_name": + err = check(key, value, contactGroup.GroupName) + case "pushover": + err = check(key, value, contactGroup.Pushover) + case "boxcar": + err = check(key, value, contactGroup.Boxcar) + case "mobiles": + err = check(key, value, contactGroup.Mobiles) + case "emails": + for _, tv := range contactGroup.Emails { + err = check(key, value, tv) + if err != nil { + return err + } + } + } + if err != nil { + return err + } + } + return nil + } +} + +func testAccContactGroupCheckDestroy(contactGroup *statuscake.ContactGroup) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*statuscake.Client) + _, err := statuscake.NewContactGroups(client).Detail(contactGroup.ContactID) + if err == nil { + return fmt.Errorf("contact_group still exists") + } + + return nil + } +} + +const testAccContactGroupConfig_basic = ` +resource "statuscake_contact_group" "exemple" { + emails= ["aaa","bbb"] + group_name= "groupname" + ping_url= "http" +} +` + +const testAccContactGroupConfig_update = ` +resource "statuscake_contact_group" "exemple" { + emails= ["aaa","bbb","ccc"] + group_name= "group" + ping_url= "https" +} +` diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index d25a866..653b9ec 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -3,7 +3,8 @@ layout: "statuscake" page_title: "Provider: StatusCake" sidebar_current: "docs-statuscake-index" description: |- - The StatusCake provider configures tests in StatusCake. + + The StatusCake provider configures tests and contact groups in StatusCake. --- # StatusCake Provider @@ -36,4 +37,11 @@ resource "statuscake_test" "google" { check_rate = 300 contact_id = 12345 } + +resource "statuscake_contact_group" "exemple" { + emails= ["email1","email2"] + group_name= "group name" + ping_url= "url" +} + ``` diff --git a/website/docs/r/contact_group.html.markdown b/website/docs/r/contact_group.html.markdown new file mode 100644 index 0000000..ed3354f --- /dev/null +++ b/website/docs/r/contact_group.html.markdown @@ -0,0 +1,47 @@ +--- +layout: "statuscake" +page_title: "StatusCake: statuscake_contact_group" +sidebar_current: "docs-statuscake-contact_group" +description: |- + The statuscake_contact_group resource allows StatusCake contact groups to be managed by Terraform. +--- + +# statuscake\_contact_group + +The contact_group resource allows StatusCake contact groups to be managed by Terraform. + +## Example Usage + +```hcl +resource "statuscake_contact_group" "exemple" { + emails= ["email1","email2"] + group_name= "group name" + ping_url= "url" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `desktop_alert` - (Required) Set to 1 To Enable Desktop Alerts +* `ping_url` - (Optional) +* `group_name` - (Optional) The internal Group Name +* `pushover` - (Optional) A Pushover Account Key +* `boxcar` - (Optional) A Boxcar API Key +* `mobiles` - (Optional) Comma Seperated List of International Format Cell Numbers +* `emails` - (Optional) List of Emails To Alert. + +## Attributes Reference + +The following attribute is exported: + +* `contact_id` - A unique identifier for the contact group. + +## Import + +StatusCake contact groups can be imported using the contact group id, e.g. + +``` +tf import statuscake_contact_group.example 123 +``` diff --git a/website/statuscake.erb b/website/statuscake.erb index d5edf59..93828d0 100644 --- a/website/statuscake.erb +++ b/website/statuscake.erb @@ -16,6 +16,9 @@ > statuscake_test + > + statuscake_contact_group + -- 2.41.0