Skip to content

Commit

Permalink
Merge pull request #16 from kvrhdn/trigger_recipient
Browse files Browse the repository at this point in the history
Add honeycombio_trigger_recipient data source
  • Loading branch information
Koenraad Verheyden authored Aug 11, 2020
2 parents ad2e752 + aafa6ac commit 9c96e69
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 7 deletions.
70 changes: 70 additions & 0 deletions docs/data-sources/trigger_recipient.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Data Source: honeycombio_trigger_recipient

Search the triggers of a dataset for a trigger recipient. The ID of the already existing trigger recipient can be used when creating new triggers. Specifying a trigger recipient by ID is necessary when creating Slack recipients using the API.

## Example Usage

```hcl
variable "dataset" {
type = string
}
# search for a trigger recipient of type "slack" and target "honeycomb-triggers" in the given dataaset
data "honeycombio_trigger_recipient" "slack" {
dataset = var.dataset
type = "slack"
target = "honeycomb-triggers"
}
data "honeycombio_query" "example" {
calculation {
op = "AVG"
column = "duration_ms"
}
}
resource "honeycombio_trigger" "example" {
name = "Requests are slower than usuals"
query_json = data.honeycombio_query.example.json
dataset = var.dataset
frequency = 600 // in seconds, 10 minutes
threshold {
op = ">"
value = 1000
}
recipient {
type = "email"
target = "[email protected]"
}
# add an already existing recipient
recipient {
id = data.honeycombio_trigger_recipient.slack
}
}
```

## Argument Reference

The following arguments are supported:

* `dataset` - (Required) Search through all triggers linked to this dataset.
* `type` - (Required) The type of recipient, allowed types are `email`, `marker`, `pagerduty` and `slack`.
* `target` - (Optional) Target of the trigger, this has another meaning depending on the type of recipient (see the table below).

Type | Target
----------|-------------------------
email | an email address
marker | name of the marker
pagerduty | _N/A_
slack | name of the channel

## Attribute Reference

In addition to all arguments above, the following attributes are exported:

* `id` - ID of the trigger recipient.
10 changes: 5 additions & 5 deletions docs/resources/trigger.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ Each trigger configuration must contain exactly one `threshold` block, which acc
* `op` - (Required) The operator to apply, allowed threshold operators are `>`, `>=`, `<`, and `<=`.
* `value` - (Required) The value to be used with the operator.

Each trigger configuration may have zero or more `recipient` blocks, which each accept the following arguments:
Each trigger configuration may have zero or more `recipient` blocks, which each accept the following arguments. A trigger recipient block can either refer to an existing recipient, i.e. a recipient that is already present in another trigger, or a new recipient. When specifying an existing recipient, only `id` must be set. To retrieve the ID of an existing recipient, refer to the [`honeycombio_trigger_recipient`](../data-sources/trigger_recipient.md) data source.

* `type` - (Required) The type of recipient, allowed types are `email`, `marker`, `pagerduty` and `slack`.
* `target` - (Optional) Target of the trigger, this has another meaning depending on the type of recipient (see the table below).
* `id` - (Optional) The ID of the recipient, this is necessary when type is Slack (see the note below).
* `type` - (Optional) The type of the trigger recipient, allowed types are `email`, `marker`, `pagerduty` and `slack`. Should not be used in combination with `id`.
* `target` - (Optional) Target of the trigger recipient, this has another meaning depending on the type of recipient (see the table below). Should not be used in combination with `id`.
* `id` - (Optional) The ID of an already existing recipient, this is necessary when type is Slack (see the note below). Should not be used in combination with `type`.

Type | Target
----------|-------------------------
Expand All @@ -79,7 +79,7 @@ marker | name of the marker
pagerduty | _N/A_
slack | name of the channel

~> **NOTE** When type is Slack you have to specify the ID. Refer to [Specifying Recipients](https://docs.honeycomb.io/api/triggers/#specifying-recipients) for more information. It's currently not possible to retrieve this ID using the Terraform provider.
~> **NOTE** Recipients of type `slack` can not be created using the API. Instead, you have to refer to existing Slack recipients using their ID. Refer to [Specifying Recipients](https://docs.honeycomb.io/api/triggers/#specifying-recipients) for more information. You can use the [`honeycombio_trigger_recipient`](../data-sources/trigger_recipient.md) data source to find an already existing recipient.

## Attribute Reference

Expand Down
56 changes: 56 additions & 0 deletions honeycombio/data_source_trigger_recipient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package honeycombio

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
honeycombio "github.com/kvrhdn/go-honeycombio"
)

func dataSourceHoneycombioSlackRecipient() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceHoneycombioSlackRecipientRead,

Schema: map[string]*schema.Schema{
"dataset": {
Type: schema.TypeString,
Required: true,
},
"type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice(validTriggerRecipientTypes, false),
},
"target": {
Type: schema.TypeString,
Optional: true,
},
},
}
}

func dataSourceHoneycombioSlackRecipientRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*honeycombio.Client)
dataset := d.Get("dataset").(string)

triggers, err := client.Triggers.List(dataset)
if err != nil {
return diag.FromErr(err)
}

searchType := honeycombio.TriggerRecipientType(d.Get("type").(string))
searchTarget := d.Get("target").(string)

for _, t := range triggers {
for _, r := range t.Recipients {
if r.Type == searchType && r.Target == searchTarget {
d.SetId(r.ID)
return nil
}
}
}

return diag.Errorf("could not find a trigger recipient in \"%s\" with type = \"%s\" and target = \"%s\"", dataset, searchType, searchTarget)
}
80 changes: 80 additions & 0 deletions honeycombio/data_source_trigger_recipient_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package honeycombio

import (
"fmt"
"regexp"
"testing"

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

func TestAccDataSourceHoneycombioTriggerRecipient_basic(t *testing.T) {
c := testAccProvider.Meta().(*honeycombio.Client)
dataset := testAccDataset()

trigger := testAccTriggerRecipientCreateTrigger(t, c, dataset)
defer testAccTriggerRecipientDeleteTrigger(t, c, dataset, trigger)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccTriggerRecipient(dataset, "email", "[email protected]"),
},
{
Config: testAccTriggerRecipient(dataset, "email", "[email protected]"),
ExpectError: regexp.MustCompile("could not find a trigger recipient in "),
},
{
Config: testAccTriggerRecipient(dataset, "slack", "[email protected]"),
ExpectError: regexp.MustCompile("could not find a trigger recipient in "),
},
},
})
}

func testAccTriggerRecipient(dataset, recipientType, target string) string {
return fmt.Sprintf(`
data "honeycombio_trigger_recipient" "test" {
dataset = "%s"
type = "%s"
target = "%s"
}`, dataset, recipientType, target)
}

func testAccTriggerRecipientCreateTrigger(t *testing.T, c *honeycombio.Client, dataset string) *honeycombio.Trigger {
trigger := &honeycombio.Trigger{
Name: "Terraform provider - acc test trigger recipient",
Query: &honeycombio.QuerySpec{
Calculations: []honeycombio.CalculationSpec{
{
Op: honeycombio.CalculateOpCount,
},
},
},
Threshold: &honeycombio.TriggerThreshold{
Op: honeycombio.TriggerThresholdOpGreaterThan,
Value: &[]float64{100}[0],
},
Recipients: []honeycombio.TriggerRecipient{
{
Type: honeycombio.TriggerRecipientTypeEmail,
Target: "[email protected]",
},
},
}
trigger, err := c.Triggers.Create(dataset, trigger)
if err != nil {
t.Error(err)
}
return trigger
}

func testAccTriggerRecipientDeleteTrigger(t *testing.T, c *honeycombio.Client, dataset string, trigger *honeycombio.Trigger) {
err := c.Triggers.Delete(dataset, trigger.ID)
if err != nil {
t.Error(err)
}
}
3 changes: 2 additions & 1 deletion honeycombio/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ func Provider() *schema.Provider {
},
},
DataSourcesMap: map[string]*schema.Resource{
"honeycombio_query": dataSourceHoneycombioQuery(),
"honeycombio_query": dataSourceHoneycombioQuery(),
"honeycombio_trigger_recipient": dataSourceHoneycombioSlackRecipient(),
},
ResourcesMap: map[string]*schema.Resource{
"honeycombio_board": newBoard(),
Expand Down
3 changes: 2 additions & 1 deletion honeycombio/resource_trigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ func newTrigger() *schema.Resource {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
// TODO can we validate either id or type+target is set?
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Expand All @@ -85,7 +86,7 @@ func newTrigger() *schema.Resource {
},
"type": {
Type: schema.TypeString,
Required: true,
Optional: true,
ValidateFunc: validation.StringInSlice(validTriggerRecipientTypes, false),
},
"target": {
Expand Down

0 comments on commit 9c96e69

Please sign in to comment.