Skip to content

Commit

Permalink
feat: New organization_repository resource (#500)
Browse files Browse the repository at this point in the history
* feat: New organization_repository resource

* feat: add tests and update docs

* feat: add secrets to gh workflow

* fix: sweep during pre-check

* ref: add deprecation message
  • Loading branch information
jianyuan authored Oct 30, 2024
1 parent 6f1f918 commit f084e70
Show file tree
Hide file tree
Showing 16 changed files with 581 additions and 29 deletions.
10 changes: 7 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,14 @@ jobs:
timeout-minutes: 30
env:
TF_ACC: "1"
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_TEST_GITHUB_INSTALLATION_ID: ${{ secrets.SENTRY_TEST_GITHUB_INSTALLATION_ID }}
SENTRY_TEST_GITHUB_REPOSITORY_IDENTIFIER: ${{ secrets.SENTRY_TEST_GITHUB_REPOSITORY_IDENTIFIER }}
SENTRY_TEST_OPSGENIE_INTEGRATION_KEY: ${{ secrets.SENTRY_TEST_OPSGENIE_INTEGRATION_KEY }}
SENTRY_TEST_OPSGENIE_ORGANIZATION: ${{ secrets.SENTRY_TEST_OPSGENIE_ORGANIZATION }}
SENTRY_TEST_ORGANIZATION: ${{ secrets.SENTRY_TEST_ORGANIZATION }}
SENTRY_TEST_PAGERDUTY_ORGANIZATION: ${{ secrets.SENTRY_TEST_PAGERDUTY_ORGANIZATION }}
SENTRY_TEST_OPSGENIE_ORGANIZATION: ${{ secrets.SENTRY_TEST_OPSGENIE_ORGANIZATION }}
SENTRY_TEST_OPSGENIE_INTEGRATION_KEY: ${{ secrets.SENTRY_TEST_OPSGENIE_INTEGRATION_KEY }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_TEST_VSTS_INSTALLATION_ID: ${{ secrets.SENTRY_TEST_VSTS_INSTALLATION_ID }}
SENTRY_TEST_VSTS_REPOSITORY_IDENTIFIER: ${{ secrets.SENTRY_TEST_VSTS_REPOSITORY_IDENTIFIER }}
run: |
go test -v -cover -timeout 30m ./...
65 changes: 65 additions & 0 deletions docs/resources/organization_repository.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "sentry_organization_repository Resource - terraform-provider-sentry"
subcategory: ""
description: |-
Organization Repository resource. This resource manages Sentry's source code management integrations.
---

# sentry_organization_repository (Resource)

Organization Repository resource. This resource manages Sentry's source code management integrations.

## Example Usage

```terraform
# GitHub
data "sentry_organization_integration" "github" {
organization = "my-organization"
provider_key = "github"
name = "my-github-organization"
}
resource "sentry_organization_repository" "github" {
organization = "my-organization"
integration_type = "github"
integration_id = data.sentry_organization_integration.github.internal_id
identifier = "my-github-organization/my-github-repo"
}
# Azure DevOps
data "sentry_organization_repository" "vsts" {
organization = "my-organization"
provider_key = "vsts"
name = "my-azure-devops-organization"
}
resource "sentry_organization_repository" "vsts" {
organization = "my-organization"
integration_type = "vsts"
integration_id = data.sentry_organization_integration.vsts.internal_id
identifier = "5febef5a-833d-4e14-b9c0-14cb638f91e6"
}
```

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

### Required

- `identifier` (String) The identifier of the repository. For GitHub, GitLab and BitBucket, it is `{organization}/{repository}`. For VSTS, it is the [repository ID](https://learn.microsoft.com/en-us/rest/api/azure/devops/git/repositories/get#get-a-repository-by-repositoryid).
- `integration_id` (String) The ID of the organization integration. Source from the URL `https://<organization>.sentry.io/settings/integrations/<integration-type>/<integration-id>/` or use the `sentry_organization_integration` data source.
- `integration_type` (String) The type of the organization integration. Supported values are `github`, `github_enterprise`, `gitlab`, `vsts` (Azure DevOps), `bitbucket`, and `bitbucket_server`.
- `organization` (String) The slug of the organization the resource belongs to.

### Read-Only

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

## Import

Import is supported using the following syntax:

```shell
terraform import sentry_organization_repository.this org-slug/integration-type/integration-id/internal-id
```
4 changes: 2 additions & 2 deletions docs/resources/organization_repository_github.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
page_title: "sentry_organization_repository_github Resource - terraform-provider-sentry"
subcategory: ""
description: |-
Sentry Github Organization Repository resource.
Sentry Github Organization Repository resource. This resource is deprecated and will be removed in the next major version of the provider. Use sentry_organization_repository instead.
---

# sentry_organization_repository_github (Resource)

Sentry Github Organization Repository resource.
Sentry Github Organization Repository resource. This resource is deprecated and will be removed in the next major version of the provider. Use `sentry_organization_repository` instead.

## Example Usage

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
terraform import sentry_organization_repository.this org-slug/integration-type/integration-id/internal-id
27 changes: 27 additions & 0 deletions examples/resources/sentry_organization_repository/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# GitHub
data "sentry_organization_integration" "github" {
organization = "my-organization"
provider_key = "github"
name = "my-github-organization"
}

resource "sentry_organization_repository" "github" {
organization = "my-organization"
integration_type = "github"
integration_id = data.sentry_organization_integration.github.internal_id
identifier = "my-github-organization/my-github-repo"
}

# Azure DevOps
data "sentry_organization_repository" "vsts" {
organization = "my-organization"
provider_key = "vsts"
name = "my-azure-devops-organization"
}

resource "sentry_organization_repository" "vsts" {
organization = "my-organization"
integration_type = "vsts"
integration_id = data.sentry_organization_integration.vsts.internal_id
identifier = "5febef5a-833d-4e14-b9c0-14cb638f91e6"
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ require (
github.com/hashicorp/terraform-plugin-log v0.9.0
github.com/hashicorp/terraform-plugin-mux v0.16.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0
github.com/jianyuan/go-sentry/v2 v2.8.1
github.com/jianyuan/go-sentry/v2 v2.8.2
golang.org/x/oauth2 v0.23.0
golang.org/x/sync v0.8.0
)
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgf
github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=
github.com/jianyuan/go-sentry/v2 v2.8.1 h1:ClC408XMHfx4AhbQlki59sctDQautn/kSu1KvfDV1Kw=
github.com/jianyuan/go-sentry/v2 v2.8.1/go.mod h1:ZMSSWRuXbIwtoH4jg2ka9ZA8x3o3zC8nkTeeqq97G7g=
github.com/jianyuan/go-sentry/v2 v2.8.2 h1:H5jdTg5dbfZykgrfRIHRZe3JU3QlsaNN0WfYjGSaRY8=
github.com/jianyuan/go-sentry/v2 v2.8.2/go.mod h1:ZMSSWRuXbIwtoH4jg2ka9ZA8x3o3zC8nkTeeqq97G7g=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
Expand Down
12 changes: 12 additions & 0 deletions internal/acctest/acctest.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ var (
// TestOpsgenieIntegrationKey is the Opsgenie integration key used for acceptance tests.
TestOpsgenieIntegrationKey = os.Getenv("SENTRY_TEST_OPSGENIE_INTEGRATION_KEY")

// TestGitHubInstallationId is the GitHub installation ID used for acceptance tests.
TestGitHubInstallationId = os.Getenv("SENTRY_TEST_GITHUB_INSTALLATION_ID")

// TestGitHubRepositoryIdentifier is the GitHub repository identifier used for acceptance tests.
TestGitHubRepositoryIdentifier = os.Getenv("SENTRY_TEST_GITHUB_REPOSITORY_IDENTIFIER")

// TestVSTSInstallationId is the VSTS installation ID used for acceptance tests.
TestVSTSInstallationId = os.Getenv("SENTRY_TEST_VSTS_INSTALLATION_ID")

// TestVSTSRepositoryIdentifier is the VSTS repository identifier used for acceptance tests.
TestVSTSRepositoryIdentifier = os.Getenv("SENTRY_TEST_VSTS_REPOSITORY_IDENTIFIER")

// SharedClient is a shared Sentry client for acceptance tests.
SharedClient *sentry.Client
)
Expand Down
13 changes: 10 additions & 3 deletions internal/provider/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,14 @@ func splitThreePartID(id, a, b, c string) (string, string, string, error) {
return parts[0], parts[1], parts[2], nil
}

func splitSentryAlertID(id string) (org string, project string, alertID string, err error) {
org, project, alertID, err = splitThreePartID(id, "organization-slug", "project-slug", "alert-id")
return
func buildFourPartID(a, b, c, d string) string {
return fmt.Sprintf("%s/%s/%s/%s", a, b, c, d)
}

func splitFourPartID(id, a, b, c, d string) (string, string, string, string, error) {
parts := strings.Split(id, "/")
if len(parts) != 4 || parts[0] == "" || parts[1] == "" || parts[2] == "" || parts[3] == "" {
return "", "", "", "", fmt.Errorf("unexpected format of ID (%s), expected %s/%s/%s/%s", id, a, b, c, d)
}
return parts[0], parts[1], parts[2], parts[3], nil
}
3 changes: 3 additions & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,15 @@ func (p *SentryProvider) Configure(ctx context.Context, req provider.ConfigureRe
}

func (p *SentryProvider) Resources(ctx context.Context) []func() resource.Resource {
// Please keep the resources sorted by name.
return []func() resource.Resource{
NewAllProjectsSpikeProtectionResource,
NewClientKeyResource,
NewIntegrationOpsgenie,
NewIntegrationPagerDuty,
NewIssueAlertResource,
NewNotificationActionResource,
NewOrganizationRepositoryResource,
NewProjectInboundDataFilterResource,
NewProjectResource,
NewProjectSpikeProtectionResource,
Expand All @@ -109,6 +111,7 @@ func (p *SentryProvider) Resources(ctx context.Context) []func() resource.Resour
}

func (p *SentryProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
// Please keep the data sources sorted by name.
return []func() datasource.DataSource{
NewAllClientKeysDataSource,
NewAllOrganizationMembersDataSource,
Expand Down
18 changes: 10 additions & 8 deletions internal/provider/resource_integration_opsgenie_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,20 @@ import (
)

func TestAccIntegrationOpsgenieResource(t *testing.T) {
if acctest.TestOpsgenieOrganization == "" {
t.Skip("Skipping test due to missing SENTRY_TEST_OPSGENIE_ORGANIZATION environment variable")
}
if acctest.TestOpsgenieIntegrationKey == "" {
t.Skip("Skipping test due to missing SENTRY_TEST_OPSGENIE_INTEGRATION_KEY environment variable")
}

teamName := acctest.RandomWithPrefix("tf-opsgenie-service")
rn := "sentry_integration_opsgenie.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
PreCheck: func() {
acctest.PreCheck(t)

if acctest.TestOpsgenieOrganization == "" {
t.Skip("Skipping test due to missing SENTRY_TEST_OPSGENIE_ORGANIZATION environment variable")
}
if acctest.TestOpsgenieIntegrationKey == "" {
t.Skip("Skipping test due to missing SENTRY_TEST_OPSGENIE_INTEGRATION_KEY environment variable")
}
},
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
CheckDestroy: func(s *terraform.State) error {
for _, rs := range s.RootModule().Resources {
Expand Down
12 changes: 7 additions & 5 deletions internal/provider/resource_integration_pagerduty_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,18 @@ import (
)

func TestAccIntegrationPagerDutyResource(t *testing.T) {
if acctest.TestPagerDutyOrganization == "" {
t.Skip("Skipping test due to missing SENTRY_TEST_PAGERDUTY_ORGANIZATION environment variable")
}

serviceName := acctest.RandomWithPrefix("tf-pagerduty-service")
integrationKey := acctest.RandomWithPrefix("tf-integration-key")
rn := "sentry_integration_pagerduty.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
PreCheck: func() {
acctest.PreCheck(t)

if acctest.TestPagerDutyOrganization == "" {
t.Skip("Skipping test due to missing SENTRY_TEST_PAGERDUTY_ORGANIZATION environment variable")
}
},
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
CheckDestroy: func(s *terraform.State) error {
for _, rs := range s.RootModule().Resources {
Expand Down
Loading

0 comments on commit f084e70

Please sign in to comment.