Skip to content

Commit

Permalink
Status page groups (#109)
Browse files Browse the repository at this point in the history
  • Loading branch information
CarwynNelson authored Jul 15, 2024
1 parent a6ae969 commit 24b6cf7
Show file tree
Hide file tree
Showing 11 changed files with 293 additions and 6 deletions.
5 changes: 4 additions & 1 deletion docs/resources/betteruptime_heartbeat_group.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ https://betterstack.com/docs/uptime/api/heartbeat-groups/
<!-- schema generated by tfplugindocs -->
## Schema

### Optional
### Required

- **name** (String) A name of the group that you can see in the dashboard.

### Optional

- **paused** (Boolean) Set to true to pause monitoring for any existing heartbeats in the group - we won't notify you about downtime. Set to false to resume monitoring for any existing heartbeats in the group.
- **sort_index** (Number) Set sort_index to specify how to sort your heartbeat groups.
- **team_name** (String) Used to specify the team the resource should be created in when using global tokens.
Expand Down
5 changes: 4 additions & 1 deletion docs/resources/betteruptime_monitor_group.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ https://betterstack.com/docs/uptime/api/monitor-groups/
<!-- schema generated by tfplugindocs -->
## Schema

### Optional
### Required

- **name** (String) A name of the group that you can see in the dashboard.

### Optional

- **paused** (Boolean) Set to true to pause monitoring for any existing monitors in the group - we won't notify you about downtime. Set to false to resume monitoring for any existing monitors in the group.
- **sort_index** (Number) Set sort_index to specify how to sort your monitor groups.
- **team_name** (String) Used to specify the team the resource should be created in when using global tokens.
Expand Down
1 change: 1 addition & 0 deletions docs/resources/betteruptime_status_page.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ https://betterstack.com/docs/uptime/api/status-pages/
- **min_incident_length** (Number) If you don't want to display short incidents on your status page, this attribute is for you.
- **password** (String, Sensitive) Set a password of your status page (we won't store it as plaintext, promise). Required when password_enabled: true. We will set password_enabled: false automatically when you send us an empty password.
- **password_enabled** (Boolean) Do you want to enable password protection on your status page?
- **status_page_group_id** (Number) Set this attribute if you want to add this status page to a status page group.
- **subscribable** (Boolean) Do you want to allow users to subscribe to your status page changes?
- **theme** (String) Choose theme of your status page. Only applicable when design: v2. Possible values: 'light', 'dark'.

Expand Down
33 changes: 33 additions & 0 deletions docs/resources/betteruptime_status_page_group.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "betteruptime_status_page_group Resource - terraform-provider-better-uptime"
subcategory: ""
description: |-
https://betterstack.com/docs/uptime/api/status-page-groups/
---

# betteruptime_status_page_group (Resource)

https://betterstack.com/docs/uptime/api/status-page-groups/



<!-- schema generated by tfplugindocs -->
## Schema

### Required

- **name** (String) A name of the group that you can see in the dashboard.

### Optional

- **sort_index** (Number) Set sort_index to specify how to sort your status page groups.
- **team_name** (String) Used to specify the team the resource should be created in when using global tokens.

### Read-Only

- **created_at** (String) The time when this status page group was created.
- **id** (String) The ID of this status page group.
- **updated_at** (String) The time when this status page group was updated.


6 changes: 6 additions & 0 deletions examples/basic/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@ resource "random_id" "status_page_subdomain" {
prefix = "tf-status-"
}

resource "betteruptime_status_page_group" "this" {
name = "Status pages from Terraform"
}

resource "betteruptime_status_page" "this" {
company_name = "Example, Inc"
company_url = "https://example.com"
timezone = "UTC"
subdomain = coalesce(var.betteruptime_status_page_subdomain, random_id.status_page_subdomain.hex)

status_page_group_id = betteruptime_status_page_group.this.id
}

resource "betteruptime_monitor" "this" {
Expand Down
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func New(opts ...Option) *schema.Provider {
"betteruptime_policy": newPolicyResource(),
"betteruptime_severity": newSeverityResource(),
"betteruptime_status_page": newStatusPageResource(),
"betteruptime_status_page_group": newStatusPageGroupResource(),
"betteruptime_status_page_section": newStatusPageSectionResource(),
"betteruptime_status_page_resource": newStatusPageResourceResource(),
"betteruptime_pagerduty_integration": newPagerdutyIntegrationResource(),
Expand Down
3 changes: 1 addition & 2 deletions internal/provider/resource_heartbeat_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ var heartbeatGroupSchema = map[string]*schema.Schema{
"name": {
Description: "A name of the group that you can see in the dashboard.",
Type: schema.TypeString,
Optional: true,
Computed: true,
Required: true,
},
"sort_index": {
Description: "Set sort_index to specify how to sort your heartbeat groups.",
Expand Down
3 changes: 1 addition & 2 deletions internal/provider/resource_monitor_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ var monitorGroupSchema = map[string]*schema.Schema{
"name": {
Description: "A name of the group that you can see in the dashboard.",
Type: schema.TypeString,
Optional: true,
Computed: true,
Required: true,
},
"sort_index": {
Description: "Set sort_index to specify how to sort your monitor groups.",
Expand Down
8 changes: 8 additions & 0 deletions internal/provider/resource_status_page.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ var statusPageSchema = map[string]*schema.Schema{
Optional: true,
Computed: true,
},
"status_page_group_id": {
Description: "Set this attribute if you want to add this status page to a status page group.",
Type: schema.TypeInt,
Optional: true,
Computed: true,
},
}

func newStatusPageResource() *schema.Resource {
Expand Down Expand Up @@ -228,6 +234,7 @@ type statusPage struct {
Theme *string `json:"theme,omitempty"`
Layout *string `json:"layout,omitempty"`
AutomaticReports *bool `json:"automatic_reports,omitempty"`
StatusPageGroupID *int `json:"status_page_group_id,omitempty"`
}

type statusPageHTTPResponse struct {
Expand Down Expand Up @@ -273,6 +280,7 @@ func statusPageRef(in *statusPage) []struct {
{k: "theme", v: &in.Theme},
{k: "layout", v: &in.Layout},
{k: "automatic_reports", v: &in.AutomaticReports},
{k: "status_page_group_id", v: &in.StatusPageGroupID},
}
}
func statusPageCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
Expand Down
150 changes: 150 additions & 0 deletions internal/provider/resource_status_page_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package provider

import (
"context"
"fmt"
"net/url"
"reflect"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

var statusPageGroupSchema = map[string]*schema.Schema{
"team_name": {
Description: "Used to specify the team the resource should be created in when using global tokens.",
Type: schema.TypeString,
Optional: true,
Default: nil,
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
return d.Id() != ""
},
},
"id": {
Description: "The ID of this status page group.",
Type: schema.TypeString,
Optional: false,
Computed: true,
},
"name": {
Description: "A name of the group that you can see in the dashboard.",
Type: schema.TypeString,
Required: true,
},
"sort_index": {
Description: "Set sort_index to specify how to sort your status page groups.",
Type: schema.TypeInt,
Optional: true,
Computed: true,
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
return !d.HasChange(k)
},
},
"created_at": {
Description: "The time when this status page group was created.",
Type: schema.TypeString,
Optional: false,
Computed: true,
},
"updated_at": {
Description: "The time when this status page group was updated.",
Type: schema.TypeString,
Optional: false,
Computed: true,
},
}

func newStatusPageGroupResource() *schema.Resource {
return &schema.Resource{
CreateContext: statusPageGroupCreate,
ReadContext: statusPageGroupRead,
UpdateContext: statusPageGroupUpdate,
DeleteContext: statusPageGroupDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Description: "https://betterstack.com/docs/uptime/api/status-page-groups/",
Schema: statusPageGroupSchema,
}
}

type statusPageGroup struct {
Name *string `json:"name,omitempty"`
SortIndex *int `json:"sort_index,omitempty"`
CreatedAt *string `json:"created_at,omitempty"`
UpdatedAt *string `json:"updated_at,omitempty"`
TeamName *string `json:"team_name,omitempty"`
}

type statusPageGroupHTTPResponse struct {
Data struct {
ID string `json:"id"`
Attributes statusPageGroup `json:"attributes"`
} `json:"data"`
}

func statusPageGroupRef(in *statusPageGroup) []struct {
k string
v interface{}
} {
// TODO: if reflect.TypeOf(in).NumField() != len([]struct)
return []struct {
k string
v interface{}
}{
{k: "name", v: &in.Name},
{k: "sort_index", v: &in.SortIndex},
{k: "created_at", v: &in.CreatedAt},
{k: "updated_at", v: &in.UpdatedAt},
}
}

func statusPageGroupCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var in statusPageGroup
for _, e := range statusPageGroupRef(&in) {
load(d, e.k, e.v)
}
load(d, "team_name", &in.TeamName)
var out statusPageGroupHTTPResponse
if err := resourceCreate(ctx, meta, "/api/v2/status-page-groups", &in, &out); err != nil {
return err
}
d.SetId(out.Data.ID)
return statusPageGroupCopyAttrs(d, &out.Data.Attributes)
}

func statusPageGroupRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var out statusPageGroupHTTPResponse
if err, ok := resourceRead(ctx, meta, fmt.Sprintf("/api/v2/status-page-groups/%s", url.PathEscape(d.Id())), &out); err != nil {
return err
} else if !ok {
d.SetId("") // Force "create" on 404.
return nil
}
return statusPageGroupCopyAttrs(d, &out.Data.Attributes)
}

func statusPageGroupCopyAttrs(d *schema.ResourceData, in *statusPageGroup) diag.Diagnostics {
var derr diag.Diagnostics
for _, e := range statusPageGroupRef(in) {
if err := d.Set(e.k, reflect.Indirect(reflect.ValueOf(e.v)).Interface()); err != nil {
derr = append(derr, diag.FromErr(err)[0])
}
}
return derr
}

func statusPageGroupUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var in statusPageGroup
var out policyHTTPResponse
for _, e := range statusPageGroupRef(&in) {
if d.HasChange(e.k) {
load(d, e.k, e.v)
}
}
return resourceUpdate(ctx, meta, fmt.Sprintf("/api/v2/status-page-groups/%s", url.PathEscape(d.Id())), &in, &out)
}

func statusPageGroupDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
return resourceDelete(ctx, meta, fmt.Sprintf("/api/v2/status-page-groups/%s", url.PathEscape(d.Id())))
}
84 changes: 84 additions & 0 deletions internal/provider/resource_status_page_group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package provider

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestResourceStatusPageGroup(t *testing.T) {
server := newResourceServer(t, "/api/v2/status-page-groups", "1")
defer server.Close()

var name = "example"

resource.Test(t, resource.TestCase{
IsUnitTest: true,
ProviderFactories: map[string]func() (*schema.Provider, error){
"betteruptime": func() (*schema.Provider, error) {
return New(WithURL(server.URL)), nil
},
},
Steps: []resource.TestStep{
// Step 1 - create.
{
Config: fmt.Sprintf(`
provider "betteruptime" {
api_token = "foo"
}
resource "betteruptime_status_page_group" "this" {
name = "%s"
sort_index = 1
}
`, name),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("betteruptime_status_page_group.this", "id"),
resource.TestCheckResourceAttr("betteruptime_status_page_group.this", "name", name),
resource.TestCheckResourceAttr("betteruptime_status_page_group.this", "sort_index", "1"),
),
},
// Step 2 - update.
{
Config: fmt.Sprintf(`
provider "betteruptime" {
api_token = "foo"
}
resource "betteruptime_status_page_group" "this" {
name = "%s"
sort_index = 0
}
`, name),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("betteruptime_status_page_group.this", "id"),
resource.TestCheckResourceAttr("betteruptime_status_page_group.this", "name", name),
resource.TestCheckResourceAttr("betteruptime_status_page_group.this", "sort_index", "0"),
),
},
// Step 3 - make no changes, check plan is empty.
{
Config: fmt.Sprintf(`
provider "betteruptime" {
api_token = "foo"
}
resource "betteruptime_status_page_group" "this" {
name = "%s"
sort_index = 0
}
`, name),
PlanOnly: true,
},
// Step 4 - destroy.
{
ResourceName: "betteruptime_status_page_group.this",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

0 comments on commit 24b6cf7

Please sign in to comment.