Skip to content

Commit

Permalink
feat: new sentry_all_projects_spike_protection resource (#429)
Browse files Browse the repository at this point in the history
  • Loading branch information
jianyuan committed May 5, 2024
1 parent b187a07 commit 6df3529
Show file tree
Hide file tree
Showing 11 changed files with 537 additions and 89 deletions.
12 changes: 1 addition & 11 deletions docs/data-sources/all_projects.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ data "sentry_projects" "default" {

### Read-Only

- `project_slugs` (Set of String) The slugs of the projects.
- `projects` (Attributes Set) The list of projects. (see [below for nested schema](#nestedatt--projects))

<a id="nestedatt--projects"></a>
Expand All @@ -40,16 +41,5 @@ Read-Only:
- `features` (Set of String) The features of this project.
- `id` (String) The ID of this project.
- `name` (String) The name of this project.
- `organization` (Attributes) The organization associated with this project. (see [below for nested schema](#nestedatt--projects--organization))
- `platform` (String) The platform of this project.
- `slug` (String) The slug of this project.
- `status` (String) The status of this project.

<a id="nestedatt--projects--organization"></a>
### Nested Schema for `projects.organization`

Read-Only:

- `id` (String) The ID of this organization.
- `name` (String) The name of this organization.
- `slug` (String) The slug of this organization.
65 changes: 65 additions & 0 deletions docs/resources/all_projects_spike_protection.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_all_projects_spike_protection Resource - terraform-provider-sentry"
subcategory: ""
description: |-
Enable spike protection for all projects in an organization.
---

# sentry_all_projects_spike_protection (Resource)

Enable spike protection for all projects in an organization.

## Example Usage

```terraform
# Enable spike protection for several projects in a Sentry organization.
resource "sentry_project" "web-app" {
organization = "my-organization"
teams = ["my-first-team"]
name = "web-app"
slug = "web-app"
platform = "go"
}
resource "sentry_project" "mobile-app" {
organization = "my-organization"
teams = ["my-second-team"]
name = "mobile-app"
slug = "mobile-app"
platform = "android"
}
resource "sentry_all_projects_spike_protection" "main" {
organization = "my-organization"
projects = [
sentry_project.web-app.id,
sentry_project.mobile-app.id,
]
enabled = true
}
# Use the `sentry_all_projects` data source to get all projects in a Sentry organization and enable spike protection for all of them.
data "sentry_all_projects" "all" {
organization = "my-organization"
}
resource "sentry_all_projects_spike_protection" "main" {
organization = data.sentry_all_projects.all.organization
projects = data.sentry_all_projects.all.project_slugs
enabled = true
}
```

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

### Required

- `enabled` (Boolean) Toggle the browser-extensions, localhost, filtered-transaction, or web-crawlers filter on or off for all projects.
- `organization` (String) The slug of the organization the resource belongs to.
- `projects` (Set of String) The slugs of the projects to enable or disable spike protection for.
2 changes: 1 addition & 1 deletion docs/resources/project_spike_protection.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ resource "sentry_project_spike_protection" "default" {

- `enabled` (Boolean) Toggle the browser-extensions, localhost, filtered-transaction, or web-crawlers filter on or off.
- `organization` (String) The slug of the organization the project belongs to.
- `project` (String) The slug of the project to create the filter for.
- `project` (String) The slug of the project to enable or disable spike protection for.

### Read-Only

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Enable spike protection for several projects in a Sentry organization.
resource "sentry_project" "web-app" {
organization = "my-organization"

teams = ["my-first-team"]
name = "web-app"
slug = "web-app"

platform = "go"
}

resource "sentry_project" "mobile-app" {
organization = "my-organization"

teams = ["my-second-team"]
name = "mobile-app"
slug = "mobile-app"

platform = "android"
}

resource "sentry_all_projects_spike_protection" "main" {
organization = "my-organization"
projects = [
sentry_project.web-app.id,
sentry_project.mobile-app.id,
]
enabled = true
}

# Use the `sentry_all_projects` data source to get all projects in a Sentry organization and enable spike protection for all of them.
data "sentry_all_projects" "all" {
organization = "my-organization"
}

resource "sentry_all_projects_spike_protection" "main" {
organization = data.sentry_all_projects.all.organization
projects = data.sentry_all_projects.all.project_slugs
enabled = true
}
61 changes: 22 additions & 39 deletions internal/provider/data_source_all_projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,13 @@ type AllProjectsDataSource struct {
}

type AllProjectsDataSourceProjectModel struct {
Id types.String `tfsdk:"id"`
Slug types.String `tfsdk:"slug"`
Name types.String `tfsdk:"name"`
Platform types.String `tfsdk:"platform"`
DateCreated types.String `tfsdk:"date_created"`
Features types.Set `tfsdk:"features"`
Color types.String `tfsdk:"color"`
Status types.String `tfsdk:"status"`
Organization OrganizationModel `tfsdk:"organization"`
Id types.String `tfsdk:"id"`
Slug types.String `tfsdk:"slug"`
Name types.String `tfsdk:"name"`
Platform types.String `tfsdk:"platform"`
DateCreated types.String `tfsdk:"date_created"`
Features types.Set `tfsdk:"features"`
Color types.String `tfsdk:"color"`
}

func (m *AllProjectsDataSourceProjectModel) Fill(project sentry.Project) error {
Expand All @@ -48,23 +46,25 @@ func (m *AllProjectsDataSourceProjectModel) Fill(project sentry.Project) error {
m.Features = types.SetValueMust(types.StringType, featureElements)

m.Color = types.StringValue(project.Color)
m.Status = types.StringValue(project.Status)
m.Organization = OrganizationModel{}
if err := m.Organization.Fill(project.Organization); err != nil {
return err
}

return nil
}

type AllProjectsDataSourceModel struct {
Organization types.String `tfsdk:"organization"`
ProjectSlugs types.Set `tfsdk:"project_slugs"`
Projects []AllProjectsDataSourceProjectModel `tfsdk:"projects"`
}

func (m *AllProjectsDataSourceModel) Fill(organization string, projects []sentry.Project) error {
m.Organization = types.StringValue(organization)

projectSlugElements := []attr.Value{}
for _, project := range projects {
projectSlugElements = append(projectSlugElements, types.StringValue(project.Slug))
}
m.ProjectSlugs = types.SetValueMust(types.StringType, projectSlugElements)

for _, project := range projects {
p := AllProjectsDataSourceProjectModel{}
if err := p.Fill(project); err != nil {
Expand All @@ -89,8 +89,14 @@ func (d *AllProjectsDataSource) Schema(ctx context.Context, req datasource.Schem
MarkdownDescription: "The slug of the organization the resource belongs to.",
Required: true,
},
"project_slugs": schema.SetAttribute{
MarkdownDescription: "The slugs of the projects.",
Computed: true,
ElementType: types.StringType,
},
"projects": schema.SetNestedAttribute{
MarkdownDescription: "The list of projects.",
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Expand Down Expand Up @@ -122,31 +128,8 @@ func (d *AllProjectsDataSource) Schema(ctx context.Context, req datasource.Schem
MarkdownDescription: "The color of this project.",
Computed: true,
},
"status": schema.StringAttribute{
MarkdownDescription: "The status of this project.",
Computed: true,
},
"organization": schema.SingleNestedAttribute{
MarkdownDescription: "The organization associated with this project.",
Computed: true,
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
MarkdownDescription: "The ID of this organization.",
Computed: true,
},
"slug": schema.StringAttribute{
MarkdownDescription: "The slug of this organization.",
Computed: true,
},
"name": schema.StringAttribute{
MarkdownDescription: "The name of this organization.",
Computed: true,
},
},
},
},
},
Computed: true,
},
},
}
Expand All @@ -161,10 +144,10 @@ func (d *AllProjectsDataSource) Read(ctx context.Context, req datasource.ReadReq
}

var allProjects []sentry.Project
params := &sentry.ListProjectsParams{}
params := &sentry.ListOrganizationProjectsParams{}

for {
projects, apiResp, err := d.client.Projects.List(ctx, params)
projects, apiResp, err := d.client.OrganizationProjects.List(ctx, data.Organization.ValueString(), params)
if err != nil {
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Read error: %s", err))
return
Expand Down
30 changes: 15 additions & 15 deletions internal/provider/data_source_all_projects_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,30 @@ import (
)

func TestAccAllProjectsDataSource(t *testing.T) {
dn := "data.sentry_all_projects.test"
team := acctest.RandomWithPrefix("tf-team")
project := acctest.RandomWithPrefix("tf-project")
teamName := acctest.RandomWithPrefix("tf-team")
projectName := acctest.RandomWithPrefix("tf-project")
rn := "data.sentry_all_projects.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: testAccAllProjectsDataSourceConfig(team, project),
Config: testAccAllProjectsDataSourceConfig(teamName, projectName),
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(dn, tfjsonpath.New("projects"), knownvalue.ListPartial(map[int]knownvalue.Check{
0: knownvalue.ObjectExact(map[string]knownvalue.Check{
statecheck.ExpectKnownValue(rn, tfjsonpath.New("organization"), knownvalue.StringExact(acctest.TestOrganization)),
statecheck.ExpectKnownValue(rn, tfjsonpath.New("project_slugs"), knownvalue.SetPartial([]knownvalue.Check{
knownvalue.StringExact(projectName),
})),
statecheck.ExpectKnownValue(rn, tfjsonpath.New("projects"), knownvalue.SetPartial([]knownvalue.Check{
knownvalue.ObjectExact(map[string]knownvalue.Check{
"id": knownvalue.NotNull(),
"slug": knownvalue.NotNull(),
"name": knownvalue.NotNull(),
"platform": knownvalue.NotNull(),
"slug": knownvalue.StringExact(projectName),
"name": knownvalue.StringExact(projectName),
"platform": knownvalue.StringExact("go"),
"date_created": knownvalue.NotNull(),
"features": knownvalue.NotNull(),
"color": knownvalue.NotNull(),
"status": knownvalue.NotNull(),
"organization": knownvalue.ObjectExact(map[string]knownvalue.Check{
"id": knownvalue.NotNull(),
"slug": knownvalue.NotNull(),
"name": knownvalue.NotNull(),
}),
}),
})),
},
Expand All @@ -63,6 +61,8 @@ resource "sentry_project" "test" {
data "sentry_all_projects" "test" {
organization = data.sentry_organization.test.slug
depends_on = [sentry_project.test]
}
`, teamName, projectName)
}
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func (p *SentryProvider) Configure(ctx context.Context, req provider.ConfigureRe

func (p *SentryProvider) Resources(ctx context.Context) []func() resource.Resource {
return []func() resource.Resource{
NewAllProjectsSpikeProtectionResource,
NewClientKeyResource,
NewIssueAlertResource,
NewNotificationActionResource,
Expand Down
Loading

0 comments on commit 6df3529

Please sign in to comment.