Skip to content

Commit a176692

Browse files
authored
Implement data source: sentry_key (#18)
1 parent ecd9d11 commit a176692

File tree

4 files changed

+298
-4
lines changed

4 files changed

+298
-4
lines changed

Diff for: example/sentry.tf

+16-4
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,20 @@ resource "sentry_project" "web_app" {
1818
name = "Web App"
1919
}
2020

21-
resource "sentry_project" "worker_app" {
22-
organization = "${sentry_team.engineering.organization}"
23-
team = "${sentry_team.engineering.id}"
24-
name = "Worker App"
21+
// Using the first parameter
22+
data "sentry_key" "via_first" {
23+
organization = "${sentry_project.web_app.organization}"
24+
project = "${sentry_project.web_app.id}"
25+
first = true
26+
}
27+
28+
// Using the name parameter
29+
data "sentry_key" "via_name" {
30+
organization = "${sentry_project.web_app.organization}"
31+
project = "${sentry_project.web_app.id}"
32+
name = "Default"
33+
}
34+
35+
output "sentry_key_dsn_secret" {
36+
value = "${data.sentry_key.via_name.dsn_secret}"
2537
}

Diff for: sentry/data_source_sentry_key.go

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package sentry
2+
3+
import (
4+
"fmt"
5+
"log"
6+
7+
"github.com/hashicorp/terraform/helper/schema"
8+
"github.com/jianyuan/go-sentry/sentry"
9+
)
10+
11+
func dataSourceSentryKey() *schema.Resource {
12+
return &schema.Resource{
13+
Read: dataSourceSentryKeyRead,
14+
15+
Schema: map[string]*schema.Schema{
16+
"organization": {
17+
Type: schema.TypeString,
18+
Required: true,
19+
ForceNew: true,
20+
},
21+
"project": {
22+
Type: schema.TypeString,
23+
Required: true,
24+
ForceNew: true,
25+
},
26+
"first": {
27+
Type: schema.TypeBool,
28+
Optional: true,
29+
Default: false,
30+
ForceNew: true,
31+
ConflictsWith: []string{"name"},
32+
},
33+
"name": {
34+
Type: schema.TypeString,
35+
Optional: true,
36+
ForceNew: true,
37+
ConflictsWith: []string{"first"},
38+
},
39+
// Computed values.
40+
"public": {
41+
Type: schema.TypeString,
42+
Computed: true,
43+
},
44+
"secret": {
45+
Type: schema.TypeString,
46+
Computed: true,
47+
},
48+
"project_id": {
49+
Type: schema.TypeInt,
50+
Computed: true,
51+
},
52+
"is_active": {
53+
Type: schema.TypeBool,
54+
Computed: true,
55+
},
56+
"rate_limit_window": {
57+
Type: schema.TypeInt,
58+
Computed: true,
59+
},
60+
"rate_limit_count": {
61+
Type: schema.TypeInt,
62+
Computed: true,
63+
},
64+
"dsn_secret": {
65+
Type: schema.TypeString,
66+
Computed: true,
67+
},
68+
"dsn_public": {
69+
Type: schema.TypeString,
70+
Computed: true,
71+
},
72+
"dsn_csp": {
73+
Type: schema.TypeString,
74+
Computed: true,
75+
},
76+
},
77+
}
78+
}
79+
80+
func dataSourceSentryKeyRead(d *schema.ResourceData, meta interface{}) error {
81+
client := meta.(*sentry.Client)
82+
83+
org := d.Get("organization").(string)
84+
project := d.Get("project").(string)
85+
86+
keys, _, err := client.ProjectKeys.List(org, project)
87+
if err != nil {
88+
return err
89+
}
90+
91+
if v, ok := d.GetOk("name"); ok {
92+
name := v.(string)
93+
for _, key := range keys {
94+
if key.Name == name {
95+
return sentryKeyAttributes(d, &key)
96+
}
97+
}
98+
return fmt.Errorf("Can't find Sentry key: %s", v)
99+
}
100+
101+
if len(keys) == 1 {
102+
log.Printf("[DEBUG] sentry_key - single key found: %s", keys[0].ID)
103+
return sentryKeyAttributes(d, &keys[0])
104+
}
105+
106+
first := d.Get("first").(bool)
107+
log.Printf("[DEBUG] sentry_key - multiple results found and `first` is set to: %t", first)
108+
if first {
109+
return sentryKeyAttributes(d, &keys[0])
110+
}
111+
112+
return fmt.Errorf("There are %d keys associate to this project. "+
113+
"To avoid ambiguity, please set `first` to true or filter the keys by specifying a `name`.",
114+
len(keys))
115+
}
116+
117+
func sentryKeyAttributes(d *schema.ResourceData, key *sentry.ProjectKey) error {
118+
d.SetId(key.ID)
119+
d.Set("name", key.Name)
120+
d.Set("public", key.Public)
121+
d.Set("secret", key.Secret)
122+
d.Set("project_id", key.ProjectID)
123+
d.Set("is_active", key.IsActive)
124+
125+
if key.RateLimit != nil {
126+
d.Set("rate_limit_window", key.RateLimit.Window)
127+
d.Set("rate_limit_count", key.RateLimit.Count)
128+
}
129+
130+
d.Set("dsn_secret", key.DSN.Secret)
131+
d.Set("dsn_public", key.DSN.Public)
132+
d.Set("dsn_csp", key.DSN.CSP)
133+
134+
return nil
135+
}

Diff for: sentry/data_source_sentry_key_test.go

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package sentry
2+
3+
import (
4+
"fmt"
5+
"regexp"
6+
"testing"
7+
8+
"github.com/hashicorp/terraform/helper/resource"
9+
"github.com/hashicorp/terraform/terraform"
10+
)
11+
12+
func TestAccSentryKeyDataSource_basic(t *testing.T) {
13+
resource.Test(t, resource.TestCase{
14+
PreCheck: func() { testAccPreCheck(t) },
15+
Providers: testAccProviders,
16+
Steps: []resource.TestStep{
17+
{
18+
Config: testAccSentryKeyDataSourceConfig,
19+
Check: resource.ComposeTestCheckFunc(
20+
testAccCheckSentryKeyDataSourceID("data.sentry_key.test_key"),
21+
resource.TestCheckResourceAttrSet("data.sentry_key.test_key", "name"),
22+
resource.TestMatchResourceAttr("data.sentry_key.test_key", "public", regexp.MustCompile(`^[0-9a-f]+$`)),
23+
resource.TestMatchResourceAttr("data.sentry_key.test_key", "secret", regexp.MustCompile(`^[0-9a-f]+$`)),
24+
resource.TestMatchResourceAttr("data.sentry_key.test_key", "project_id", regexp.MustCompile(`^\d+$`)),
25+
resource.TestCheckResourceAttrSet("data.sentry_key.test_key", "is_active"),
26+
resource.TestMatchResourceAttr("data.sentry_key.test_key", "dsn_secret", regexp.MustCompile(`^https://`)),
27+
resource.TestMatchResourceAttr("data.sentry_key.test_key", "dsn_public", regexp.MustCompile(`^https://`)),
28+
resource.TestMatchResourceAttr("data.sentry_key.test_key", "dsn_csp", regexp.MustCompile(`^https://`)),
29+
),
30+
},
31+
},
32+
})
33+
}
34+
35+
func TestAccSentryKeyDataSource_first(t *testing.T) {
36+
resource.Test(t, resource.TestCase{
37+
PreCheck: func() { testAccPreCheck(t) },
38+
Providers: testAccProviders,
39+
Steps: []resource.TestStep{
40+
{
41+
Config: testAccSentryKeyDataSourceFirstConfig,
42+
Check: resource.ComposeTestCheckFunc(
43+
testAccCheckSentryKeyDataSourceID("data.sentry_key.test_key"),
44+
),
45+
},
46+
},
47+
})
48+
}
49+
50+
func TestAccSentryKeyDataSource_name(t *testing.T) {
51+
resource.Test(t, resource.TestCase{
52+
PreCheck: func() { testAccPreCheck(t) },
53+
Providers: testAccProviders,
54+
Steps: []resource.TestStep{
55+
{
56+
Config: testAccSentryKeyDataSourceNameConfig,
57+
Check: resource.ComposeTestCheckFunc(
58+
testAccCheckSentryKeyDataSourceID("data.sentry_key.default_key"),
59+
),
60+
},
61+
},
62+
})
63+
}
64+
65+
func testAccCheckSentryKeyDataSourceID(n string) resource.TestCheckFunc {
66+
return func(s *terraform.State) error {
67+
rs, ok := s.RootModule().Resources[n]
68+
if !ok {
69+
return fmt.Errorf("Can't find Sentry key: %s", n)
70+
}
71+
72+
if rs.Primary.ID == "" {
73+
return fmt.Errorf("Sentry key data source ID not set")
74+
}
75+
76+
return nil
77+
}
78+
}
79+
80+
var testAccSentryKeyDataSourceConfig = fmt.Sprintf(`
81+
resource "sentry_team" "test_team" {
82+
organization = "%s"
83+
name = "Test team"
84+
}
85+
86+
resource "sentry_project" "test_project" {
87+
organization = "%s"
88+
team = "${sentry_team.test_team.id}"
89+
name = "Test project"
90+
}
91+
92+
data "sentry_key" "test_key" {
93+
organization = "%s"
94+
project = "${sentry_project.test_project.id}"
95+
}
96+
`, testOrganization, testOrganization, testOrganization)
97+
98+
// Testing first parameter
99+
var testAccSentryKeyDataSourceFirstConfig = fmt.Sprintf(`
100+
resource "sentry_team" "test_team" {
101+
organization = "%s"
102+
name = "Test team"
103+
}
104+
105+
resource "sentry_project" "test_project" {
106+
organization = "%s"
107+
team = "${sentry_team.test_team.id}"
108+
name = "Test project"
109+
}
110+
111+
resource "sentry_key" "test_key_2" {
112+
organization = "%s"
113+
project = "${sentry_project.test_project.id}"
114+
name = "Test key 2"
115+
}
116+
117+
data "sentry_key" "test_key" {
118+
organization = "%s"
119+
project = "${sentry_project.test_project.id}"
120+
first = true
121+
}
122+
`, testOrganization, testOrganization, testOrganization, testOrganization)
123+
124+
// Testing name parameter
125+
// A key named "Default" is always created along with the project
126+
var testAccSentryKeyDataSourceNameConfig = fmt.Sprintf(`
127+
resource "sentry_team" "test_team" {
128+
organization = "%s"
129+
name = "Test team"
130+
}
131+
132+
resource "sentry_project" "test_project" {
133+
organization = "%s"
134+
team = "${sentry_team.test_team.id}"
135+
name = "Test project"
136+
}
137+
138+
data "sentry_key" "default_key" {
139+
organization = "%s"
140+
project = "${sentry_project.test_project.id}"
141+
name = "Default"
142+
}
143+
`, testOrganization, testOrganization, testOrganization)

Diff for: sentry/provider.go

+4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ func Provider() terraform.ResourceProvider {
3131
"sentry_plugin": resourceSentryPlugin(),
3232
},
3333

34+
DataSourcesMap: map[string]*schema.Resource{
35+
"sentry_key": dataSourceSentryKey(),
36+
},
37+
3438
ConfigureFunc: providerConfigure,
3539
}
3640
}

0 commit comments

Comments
 (0)