Skip to content

Commit 6ca1820

Browse files
committed
Document alert rules and add tests
1 parent fd0d6a1 commit 6ca1820

File tree

4 files changed

+153
-27
lines changed

4 files changed

+153
-27
lines changed

Diff for: docs/resources/rule.md

+20-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# sentry_rule Resource
22

3-
Sentry Rule resource.
3+
Sentry Rule resource. Note that there's no public documentation for the values of conditions, filters, and actions. You can either inspect the request payload sent when creating or editing an alert rule on Sentry or inspect [Sentry's rules registry in the source code](https://github.com/getsentry/sentry/tree/master/src/sentry/rules).
44

55
## Example Usage
66

@@ -15,17 +15,24 @@ resource "sentry_rule" "default" {
1515
1616
conditions = [
1717
{
18-
id = "sentry.rules.conditions.event_frequency.EventFrequencyCondition"
19-
value = 500
20-
interval = "1h"
18+
id = "sentry.rules.conditions.first_seen_event.FirstSeenEventCondition"
19+
name = "A new issue is created"
20+
}
21+
]
22+
23+
filters = [
24+
{
25+
id = "sentry.rules.filters.assigned_to.AssignedToFilter"
26+
targetType = "Unassigned"
2127
}
2228
]
2329
2430
actions = [
2531
{
26-
id = "sentry.integrations.slack.notify_action.SlackNotifyServiceAction"
27-
channel = "#alerts"
28-
workspace = "12345"
32+
id = "sentry.mail.actions.NotifyEmailAction"
33+
name = "Send an email to IssueOwners"
34+
targetIdentifier = ""
35+
targetType = "IssueOwners"
2936
}
3037
]
3138
}
@@ -37,19 +44,19 @@ The following arguments are supported:
3744

3845
- `organization` - (Required) The slug of the organization the plugin should be enabled for.
3946
- `project` - (Required) The slug of the project the plugin should be enabled for.
40-
- `action_match` - (Optional) Use `all` to trigger alerting when all conditions are met, and `any` when at least a condition is met. Defaults to `any`.
47+
- `name` - (Required) Name for this alert.
48+
- `action_match` - (Optional) Use `all` to trigger alerting when all conditions are met, and `any` when at. least a condition is met. Defaults to `any`.
4149
- `frequency` - (Optional) Perform actions at most once every `X` minutes for this issue. Defaults to `30`.
42-
- `environment` - (Optional) Environment name
43-
- `actions` - (Required) List of actions
44-
- `conditions` - (Required) List of conditions
50+
- `environment` - (Optional) Environment for these conditions to apply to.
51+
- `conditions` - (Required) List of conditions.
52+
- `filters` - (Optional) List of filters.
53+
- `actions` - (Required) List of actions.
4554

4655
## Attribute Reference
4756

4857
The following attributes are exported:
4958

5059
- `id` - The ID of the created rule.
5160
- `name` - The name of the created rule.
52-
- `actions` - The rule's actions.
53-
- `conditions` - The rule's conditions.
5461
- `frequency` - The rule's frequency.
5562
- `environment` - The rule's environment.

Diff for: go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ require (
1313
github.com/dghubble/sling v1.3.0 // indirect
1414
github.com/fatih/color v1.9.0 // indirect
1515
github.com/go-git/go-git/v5 v5.2.0 // indirect
16-
github.com/hashicorp/errwrap v1.1.0
16+
github.com/hashicorp/errwrap v1.1.0 // indirect
1717
github.com/hashicorp/go-hclog v0.14.1 // indirect
1818
github.com/hashicorp/go-multierror v1.1.0 // indirect
1919
github.com/hashicorp/go-uuid v1.0.2 // indirect

Diff for: sentry/resource_sentry_project_rule.go

+3-13
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"errors"
55
"fmt"
66

7-
"github.com/hashicorp/errwrap"
87
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
98
"github.com/jianyuan/go-sentry/sentry"
109
"github.com/mitchellh/mapstructure"
@@ -68,7 +67,7 @@ func resourceSentryRule() *schema.Resource {
6867
},
6968
"filters": {
7069
Type: schema.TypeList,
71-
Required: true,
70+
Optional: true,
7271
Elem: &schema.Schema{
7372
Type: schema.TypeMap,
7473
},
@@ -195,15 +194,6 @@ func resourceSentryRuleRead(d *schema.ResourceData, meta interface{}) error {
195194

196195
d.SetId(rule.ID)
197196
d.Set("name", rule.Name)
198-
if err := d.Set("actions", rule.Actions); err != nil {
199-
return errwrap.Wrapf("Unable to store rule 'actions' attribute: {{err}}", err)
200-
}
201-
if err := d.Set("conditions", rule.Conditions); err != nil {
202-
return errwrap.Wrapf("Unable to store rule 'conditions' attribute: {{err}}", err)
203-
}
204-
if err := d.Set("filters", rule.Filters); err != nil {
205-
return errwrap.Wrapf("Unable to store rule 'filters' attribute: {{err}}", err)
206-
}
207197
d.Set("frequency", rule.Frequency)
208198
d.Set("environment", rule.Environment)
209199

@@ -238,13 +228,13 @@ func resourceSentryRuleUpdate(d *schema.ResourceData, meta interface{}) error {
238228
conditions := make([]sentry.ConditionType, len(inputConditions))
239229
for i, ic := range inputConditions {
240230
var condition sentry.ConditionType
241-
mapstructure.Decode(ic, &condition)
231+
mapstructure.WeakDecode(ic, &condition)
242232
conditions[i] = condition
243233
}
244234
actions := make([]sentry.ActionType, len(inputActions))
245235
for i, ia := range inputActions {
246236
var action sentry.ActionType
247-
mapstructure.Decode(ia, &action)
237+
mapstructure.WeakDecode(ia, &action)
248238
actions[i] = action
249239
}
250240
filters := make([]sentry.FilterType, len(inputFilters))

Diff for: sentry/resource_sentry_project_rule_test.go

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package sentry
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"testing"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
10+
"github.com/jianyuan/go-sentry/sentry"
11+
)
12+
13+
func TestAccSentryProjectRule_basic(t *testing.T) {
14+
var rule sentry.Rule
15+
16+
resource.Test(t, resource.TestCase{
17+
PreCheck: func() { testAccPreCheck(t) },
18+
Providers: testAccProviders,
19+
CheckDestroy: testAccCheckSentryProjectRuleDestroy,
20+
Steps: []resource.TestStep{
21+
{
22+
Config: testAccSentryProjectRuleConfig,
23+
Check: resource.ComposeTestCheckFunc(
24+
testAccCheckSentryProjectRuleExists("sentry_rule.test_rule", &rule),
25+
resource.TestCheckResourceAttr("sentry_rule.test_rule", "name", "Test rule"),
26+
resource.TestCheckResourceAttr("sentry_rule.test_rule", "environment", ""),
27+
resource.TestCheckResourceAttr("sentry_rule.test_rule", "frequency", "30"),
28+
),
29+
},
30+
},
31+
})
32+
}
33+
34+
func testAccCheckSentryProjectRuleDestroy(s *terraform.State) error {
35+
client := testAccProvider.Meta().(*sentry.Client)
36+
37+
for _, rs := range s.RootModule().Resources {
38+
if rs.Type != "sentry_rule" {
39+
continue
40+
}
41+
42+
rules, resp, err := client.Rules.List(testOrganization, rs.Primary.Attributes["project"])
43+
if err == nil {
44+
for _, rule := range rules {
45+
if rule.ID == rs.Primary.ID {
46+
return errors.New("Project rule still exists")
47+
}
48+
}
49+
}
50+
if resp.StatusCode != 404 {
51+
return err
52+
}
53+
return nil
54+
}
55+
56+
return nil
57+
}
58+
59+
func testAccCheckSentryProjectRuleExists(n string, rule *sentry.Rule) resource.TestCheckFunc {
60+
return func(s *terraform.State) error {
61+
rs, ok := s.RootModule().Resources[n]
62+
if !ok {
63+
return fmt.Errorf("Not found: %s", n)
64+
}
65+
66+
if rs.Primary.ID == "" {
67+
return errors.New("No project ID is set")
68+
}
69+
70+
client := testAccProvider.Meta().(*sentry.Client)
71+
sentryRules, _, err := client.Rules.List(
72+
rs.Primary.Attributes["organization"],
73+
rs.Primary.Attributes["project"],
74+
)
75+
if err != nil {
76+
return err
77+
}
78+
for _, sentryRule := range sentryRules {
79+
if sentryRule.ID == rs.Primary.ID {
80+
*rule = sentryRule
81+
break
82+
}
83+
}
84+
return nil
85+
}
86+
}
87+
88+
var testAccSentryProjectRuleConfig = fmt.Sprintf(`
89+
resource "sentry_team" "test_team" {
90+
organization = "%s"
91+
name = "Test team"
92+
}
93+
94+
resource "sentry_project" "test_project" {
95+
organization = "%s"
96+
team = "${sentry_team.test_team.id}"
97+
name = "Test project"
98+
platform = "go"
99+
}
100+
101+
resource "sentry_rule" "test_rule" {
102+
organization = "%s"
103+
project = "${sentry_project.test_project.id}"
104+
name = "Test rule"
105+
106+
conditions = [
107+
{
108+
id = "sentry.rules.conditions.first_seen_event.FirstSeenEventCondition"
109+
name = "A new issue is created"
110+
}
111+
]
112+
113+
filters = [
114+
{
115+
id = "sentry.rules.filters.assigned_to.AssignedToFilter"
116+
targetType = "Unassigned"
117+
}
118+
]
119+
120+
actions = [
121+
{
122+
id = "sentry.mail.actions.NotifyEmailAction"
123+
name = "Send an email to IssueOwners"
124+
targetIdentifier = ""
125+
targetType = "IssueOwners"
126+
}
127+
]
128+
}
129+
`, testOrganization, testOrganization, testOrganization)

0 commit comments

Comments
 (0)