Skip to content

Commit

Permalink
separate resource for dst works locally
Browse files Browse the repository at this point in the history
  • Loading branch information
obs-gh-owengoebel committed Jul 31, 2024
1 parent 985ac0f commit 793fc25
Show file tree
Hide file tree
Showing 7 changed files with 257 additions and 10 deletions.
2 changes: 2 additions & 0 deletions client/internal/meta/operation/monitorv2_destination.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ mutation deleteMonitorV2Destination($id: ObjectId!) {
}
}

# @genqlient(for: "ActionDestinationLinkInput.sendEndNotifications", omitempty: true)
# @genqlient(for: "ActionDestinationLinkInput.sendRemindersInterval", omitempty: true)
mutation saveActionWithDestinationLinks(
$actionId: ObjectId!,
$destinationLinks: [ActionDestinationLinkInput!]!
Expand Down
4 changes: 2 additions & 2 deletions client/meta/genqlient.generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions client/oid/oid.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ func (t Type) IsValid() bool {
case TypeMonitorAction:
case TypeMonitorActionAttachment:
case TypeMonitorV2:
case TypeMonitorV2Action:
case TypeMonitorV2Destination:
case TypePoller:
case TypePreferredPath:
case TypeUser:
Expand Down
50 changes: 50 additions & 0 deletions docs/resources/monitor_v2_destination.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "observe_monitor_v2_destination Resource - terraform-provider-observe"
subcategory: ""
description: |-
---
# observe_monitor_v2_destination



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

### Required

- `action` (String)
- `name` (String)
- `type` (String)
- `workspace` (String)

### Optional

- `description` (String)
- `email` (Block List) (see [below for nested schema](#nestedblock--email))
- `icon_url` (String)
- `webhook` (Block List) (see [below for nested schema](#nestedblock--webhook))

### Read-Only

- `id` (String) The ID of this resource.
- `oid` (String)

<a id="nestedblock--email"></a>
### Nested Schema for `email`

Optional:

- `addresses` (List of String)
- `users` (List of String)


<a id="nestedblock--webhook"></a>
### Nested Schema for `webhook`

Required:

- `method` (String)
- `url` (String)

1 change: 1 addition & 0 deletions observe/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ func Provider() *schema.Provider {
"observe_monitor": resourceMonitor(),
"observe_monitor_v2": resourceMonitorV2(),
"observe_monitor_v2_action": resourceMonitorV2Action(),
"observe_monitor_v2_destination": resourceMonitorV2Destination(),
"observe_board": resourceBoard(),
"observe_poller": resourcePoller(),
"observe_datastream": resourceDatastream(),
Expand Down
46 changes: 38 additions & 8 deletions observe/resource_monitor_v2_destination.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,36 @@ import (
"github.com/observeinc/terraform-provider-observe/client/oid"
)

/************************************************************
* *
* FOR WHOEVER GETS PUT ON THIS TASK AFTER I LEAVE: *
* *
* This file was written when the API used to require *
* separate calls for creating a monv2 action and a *
* destination. This is why, for example, the function *
* resourceMonitorV2DestinationCreate calls 2 create *
* API calls (one to make the action, another for dest). *
* If you're reading this message with the intent of *
* modifying this file, the API has probably changed *
* so that a shared action and inlined destination can *
* be edited in a single API call, which is likely *
* what you were asked to change about this code. *
* *
* If possible, please do NOT remove any params from the *
* existing schema or add any new required params. I *
* tried to write the schema so that it would map onto *
* the new API relatively cleanly. You probably won't *
* need to change the schema, but you'll likely need to *
* change how the variables read from said schema are *
* arranged into the inputs fed to the API call. *
* *
* After making the changes, please delete this comment. *
* *
* Thanks! :) *
* - Owen *
* *
***********************************************************/

func resourceMonitorV2Destination() *schema.Resource {
return &schema.Resource{
CreateContext: resourceMonitorV2DestinationCreate,
Expand Down Expand Up @@ -39,7 +69,7 @@ func resourceMonitorV2Destination() *schema.Resource {
Type: schema.TypeList,
Optional: true,
ExactlyOneOf: []string{"email", "webhook"},
Elem: &schema.Resource{},
Elem: monitorV2EmailDestinationResource(),
},
"webhook": { // MonitorV2WebhookDestinationInput
Type: schema.TypeList,
Expand All @@ -51,7 +81,7 @@ func resourceMonitorV2Destination() *schema.Resource {
Type: schema.TypeString,
Required: true,
},
"iconUrl": { // String
"icon_url": { // String
Type: schema.TypeString,
Optional: true,
},
Expand Down Expand Up @@ -122,7 +152,7 @@ func resourceMonitorV2DestinationCreate(ctx context.Context, data *schema.Resour
actOID, _ := oid.NewOID(data.Get("action").(string))
dstLinks := []gql.ActionDestinationLinkInput{
{
DestinationID: id.Id,
DestinationID: result.Id,
},
}
_, err = client.Meta.SaveActionWithDestinationLinks(ctx, actOID.Id, dstLinks)
Expand Down Expand Up @@ -185,7 +215,7 @@ func resourceMonitorV2DestinationRead(ctx context.Context, data *schema.Resource
diags = append(diags, diag.FromErr(err)...)
}

if err := data.Set("id", dest.Oid().String()); err != nil {
if err := data.Set("oid", dest.Oid().String()); err != nil {
diags = append(diags, diag.FromErr(err)...)
}

Expand Down Expand Up @@ -233,7 +263,7 @@ func resourceMonitorV2DestinationDelete(ctx context.Context, data *schema.Resour
return diags
}

func monitorV2FlattenEmailDestination(gqlEmail gql.MonitorV2EmailDestination) interface{} {
func monitorV2FlattenEmailDestination(gqlEmail gql.MonitorV2EmailDestination) []interface{} {
email := make(map[string]interface{})
if len(gqlEmail.Addresses) > 0 {
addrs := make([]string, 0)
Expand All @@ -249,15 +279,15 @@ func monitorV2FlattenEmailDestination(gqlEmail gql.MonitorV2EmailDestination) in
}
email["users"] = uidStrs
}
return email
return []interface{}{email}
}

func monitorv2FlattenWebhookDestination(gqlWebhook gql.MonitorV2WebhookDestination) interface{} {
func monitorv2FlattenWebhookDestination(gqlWebhook gql.MonitorV2WebhookDestination) []interface{} {
webhook := map[string]interface{}{
"url": gqlWebhook.Url,
"method": toSnake(string(gqlWebhook.Method)),
}
return webhook
return []interface{}{webhook}
}

func newMonitorV2DestinationInput(data *schema.ResourceData) (input *gql.MonitorV2DestinationInput, diags diag.Diagnostics) {
Expand Down
162 changes: 162 additions & 0 deletions observe/resource_monitor_v2_destination_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package observe

import (
"fmt"
"testing"

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

func TestAccObserveMonitorV2DestinationEmail(t *testing.T) {
randomPrefix := acctest.RandomWithPrefix("tf")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(monitorV2ConfigPreamble+`
resource "observe_monitor_v2" "first" {
workspace = data.observe_workspace.default.oid
rule_kind = "count"
name = "%[1]s"
lookback_time = "30m"
comment = "a descriptive comment"
inputs = {
"test" = observe_datastream.test.dataset
}
stage {
pipeline = <<-EOF
colmake kind:"test", description:"test"
EOF
output_stage = true
}
stage {
pipeline = <<-EOF
filter kind ~ "test"
EOF
}
rules {
level = "informational"
count {
compare_values {
compare_fn = "greater"
value_int64 = [0]
}
}
}
scheduling {
interval {
interval = "15m"
randomize = "0"
}
}
}
resource "observe_monitor_v2_action" "act" {
workspace = data.observe_workspace.default.oid
type = "email"
email {
subject = "somebody once told me"
body = "the world is gonna roll me"
fragments = jsonencode({
foo = "bar"
})
}
name = "%[1]s"
description = "an interesting description"
}
`, randomPrefix),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("observe_monitor_v2_action.act", "workspace"),
resource.TestCheckResourceAttr("observe_monitor_v2_action.act", "name", randomPrefix),
resource.TestCheckResourceAttr("observe_monitor_v2_action.act", "type", "email"),
resource.TestCheckResourceAttr("observe_monitor_v2_action.act", "description", "an interesting description"),
resource.TestCheckResourceAttr("observe_monitor_v2_action.act", "email.0.fragments", "{\"foo\":\"bar\"}"),
resource.TestCheckResourceAttr("observe_monitor_v2_action.act", "email.0.subject", "somebody once told me"),
resource.TestCheckResourceAttr("observe_monitor_v2_action.act", "email.0.body", "the world is gonna roll me"),
),
},
},
})
}

func TestAccObserveMonitorV2DestinationWebhook(t *testing.T) {
randomPrefix := acctest.RandomWithPrefix("tf")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(monitorV2ConfigPreamble+`
resource "observe_monitor_v2" "first" {
workspace = data.observe_workspace.default.oid
rule_kind = "count"
name = "%[1]s"
lookback_time = "30m"
comment = "a descriptive comment"
inputs = {
"test" = observe_datastream.test.dataset
}
stage {
pipeline = <<-EOF
colmake kind:"test", description:"test"
EOF
output_stage = true
}
stage {
pipeline = <<-EOF
filter kind ~ "test"
EOF
}
rules {
level = "informational"
count {
compare_values {
compare_fn = "greater"
value_int64 = [0]
}
}
}
scheduling {
interval {
interval = "15m"
randomize = "0"
}
}
}
resource "observe_monitor_v2_action" "act" {
workspace = data.observe_workspace.default.oid
type = "webhook"
webhook {
headers {
header = "never gonna give you up"
value = "never gonna let you down"
}
body = "never gonna run around and desert you"
fragments = jsonencode({
foo = "bar"
})
}
name = "%[1]s"
description = "an interesting description"
}
`, randomPrefix),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("observe_monitor_v2_action.act", "workspace"),
resource.TestCheckResourceAttr("observe_monitor_v2_action.act", "name", randomPrefix),
resource.TestCheckResourceAttr("observe_monitor_v2_action.act", "type", "webhook"),
resource.TestCheckResourceAttr("observe_monitor_v2_action.act", "description", "an interesting description"),
resource.TestCheckResourceAttr("observe_monitor_v2_action.act", "webhook.0.fragments", "{\"foo\":\"bar\"}"),
resource.TestCheckResourceAttr("observe_monitor_v2_action.act", "webhook.0.headers.0.header", "never gonna give you up"),
resource.TestCheckResourceAttr("observe_monitor_v2_action.act", "webhook.0.headers.0.value", "never gonna let you down"),
resource.TestCheckResourceAttr("observe_monitor_v2_action.act", "webhook.0.body", "never gonna run around and desert you"),
),
},
},
})
}

0 comments on commit 793fc25

Please sign in to comment.