Skip to content

Commit

Permalink
Implement data source: sentry_key (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
jianyuan authored Nov 11, 2017
1 parent ecd9d11 commit a176692
Show file tree
Hide file tree
Showing 4 changed files with 298 additions and 4 deletions.
20 changes: 16 additions & 4 deletions example/sentry.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,20 @@ resource "sentry_project" "web_app" {
name = "Web App"
}

resource "sentry_project" "worker_app" {
organization = "${sentry_team.engineering.organization}"
team = "${sentry_team.engineering.id}"
name = "Worker App"
// Using the first parameter
data "sentry_key" "via_first" {
organization = "${sentry_project.web_app.organization}"
project = "${sentry_project.web_app.id}"
first = true
}

// Using the name parameter
data "sentry_key" "via_name" {
organization = "${sentry_project.web_app.organization}"
project = "${sentry_project.web_app.id}"
name = "Default"
}

output "sentry_key_dsn_secret" {
value = "${data.sentry_key.via_name.dsn_secret}"
}
135 changes: 135 additions & 0 deletions sentry/data_source_sentry_key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package sentry

import (
"fmt"
"log"

"github.com/hashicorp/terraform/helper/schema"
"github.com/jianyuan/go-sentry/sentry"
)

func dataSourceSentryKey() *schema.Resource {
return &schema.Resource{
Read: dataSourceSentryKeyRead,

Schema: map[string]*schema.Schema{
"organization": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"project": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"first": {
Type: schema.TypeBool,
Optional: true,
Default: false,
ForceNew: true,
ConflictsWith: []string{"name"},
},
"name": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ConflictsWith: []string{"first"},
},
// Computed values.
"public": {
Type: schema.TypeString,
Computed: true,
},
"secret": {
Type: schema.TypeString,
Computed: true,
},
"project_id": {
Type: schema.TypeInt,
Computed: true,
},
"is_active": {
Type: schema.TypeBool,
Computed: true,
},
"rate_limit_window": {
Type: schema.TypeInt,
Computed: true,
},
"rate_limit_count": {
Type: schema.TypeInt,
Computed: true,
},
"dsn_secret": {
Type: schema.TypeString,
Computed: true,
},
"dsn_public": {
Type: schema.TypeString,
Computed: true,
},
"dsn_csp": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func dataSourceSentryKeyRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*sentry.Client)

org := d.Get("organization").(string)
project := d.Get("project").(string)

keys, _, err := client.ProjectKeys.List(org, project)
if err != nil {
return err
}

if v, ok := d.GetOk("name"); ok {
name := v.(string)
for _, key := range keys {
if key.Name == name {
return sentryKeyAttributes(d, &key)
}
}
return fmt.Errorf("Can't find Sentry key: %s", v)
}

if len(keys) == 1 {
log.Printf("[DEBUG] sentry_key - single key found: %s", keys[0].ID)
return sentryKeyAttributes(d, &keys[0])
}

first := d.Get("first").(bool)
log.Printf("[DEBUG] sentry_key - multiple results found and `first` is set to: %t", first)
if first {
return sentryKeyAttributes(d, &keys[0])
}

return fmt.Errorf("There are %d keys associate to this project. "+
"To avoid ambiguity, please set `first` to true or filter the keys by specifying a `name`.",
len(keys))
}

func sentryKeyAttributes(d *schema.ResourceData, key *sentry.ProjectKey) error {
d.SetId(key.ID)
d.Set("name", key.Name)
d.Set("public", key.Public)
d.Set("secret", key.Secret)
d.Set("project_id", key.ProjectID)
d.Set("is_active", key.IsActive)

if key.RateLimit != nil {
d.Set("rate_limit_window", key.RateLimit.Window)
d.Set("rate_limit_count", key.RateLimit.Count)
}

d.Set("dsn_secret", key.DSN.Secret)
d.Set("dsn_public", key.DSN.Public)
d.Set("dsn_csp", key.DSN.CSP)

return nil
}
143 changes: 143 additions & 0 deletions sentry/data_source_sentry_key_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package sentry

import (
"fmt"
"regexp"
"testing"

"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestAccSentryKeyDataSource_basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccSentryKeyDataSourceConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckSentryKeyDataSourceID("data.sentry_key.test_key"),
resource.TestCheckResourceAttrSet("data.sentry_key.test_key", "name"),
resource.TestMatchResourceAttr("data.sentry_key.test_key", "public", regexp.MustCompile(`^[0-9a-f]+$`)),
resource.TestMatchResourceAttr("data.sentry_key.test_key", "secret", regexp.MustCompile(`^[0-9a-f]+$`)),
resource.TestMatchResourceAttr("data.sentry_key.test_key", "project_id", regexp.MustCompile(`^\d+$`)),
resource.TestCheckResourceAttrSet("data.sentry_key.test_key", "is_active"),
resource.TestMatchResourceAttr("data.sentry_key.test_key", "dsn_secret", regexp.MustCompile(`^https://`)),
resource.TestMatchResourceAttr("data.sentry_key.test_key", "dsn_public", regexp.MustCompile(`^https://`)),
resource.TestMatchResourceAttr("data.sentry_key.test_key", "dsn_csp", regexp.MustCompile(`^https://`)),
),
},
},
})
}

func TestAccSentryKeyDataSource_first(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccSentryKeyDataSourceFirstConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckSentryKeyDataSourceID("data.sentry_key.test_key"),
),
},
},
})
}

func TestAccSentryKeyDataSource_name(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccSentryKeyDataSourceNameConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckSentryKeyDataSourceID("data.sentry_key.default_key"),
),
},
},
})
}

func testAccCheckSentryKeyDataSourceID(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Can't find Sentry key: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("Sentry key data source ID not set")
}

return nil
}
}

var testAccSentryKeyDataSourceConfig = fmt.Sprintf(`
resource "sentry_team" "test_team" {
organization = "%s"
name = "Test team"
}
resource "sentry_project" "test_project" {
organization = "%s"
team = "${sentry_team.test_team.id}"
name = "Test project"
}
data "sentry_key" "test_key" {
organization = "%s"
project = "${sentry_project.test_project.id}"
}
`, testOrganization, testOrganization, testOrganization)

// Testing first parameter
var testAccSentryKeyDataSourceFirstConfig = fmt.Sprintf(`
resource "sentry_team" "test_team" {
organization = "%s"
name = "Test team"
}
resource "sentry_project" "test_project" {
organization = "%s"
team = "${sentry_team.test_team.id}"
name = "Test project"
}
resource "sentry_key" "test_key_2" {
organization = "%s"
project = "${sentry_project.test_project.id}"
name = "Test key 2"
}
data "sentry_key" "test_key" {
organization = "%s"
project = "${sentry_project.test_project.id}"
first = true
}
`, testOrganization, testOrganization, testOrganization, testOrganization)

// Testing name parameter
// A key named "Default" is always created along with the project
var testAccSentryKeyDataSourceNameConfig = fmt.Sprintf(`
resource "sentry_team" "test_team" {
organization = "%s"
name = "Test team"
}
resource "sentry_project" "test_project" {
organization = "%s"
team = "${sentry_team.test_team.id}"
name = "Test project"
}
data "sentry_key" "default_key" {
organization = "%s"
project = "${sentry_project.test_project.id}"
name = "Default"
}
`, testOrganization, testOrganization, testOrganization)
4 changes: 4 additions & 0 deletions sentry/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ func Provider() terraform.ResourceProvider {
"sentry_plugin": resourceSentryPlugin(),
},

DataSourcesMap: map[string]*schema.Resource{
"sentry_key": dataSourceSentryKey(),
},

ConfigureFunc: providerConfigure,
}
}
Expand Down

0 comments on commit a176692

Please sign in to comment.