Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 0.1.0 (Unreleased)

FEATURES:

* **New Resource:** `sendgrid_bounce_settings` - Manage bounce settings for your SendGrid account, including soft bounce purge configuration
* **New Data Source:** `sendgrid_bounce_settings` - Retrieve current bounce settings from your SendGrid account
39 changes: 39 additions & 0 deletions docs/data-sources/bounce_settings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "sendgrid_bounce_settings Data Source - terraform-provider-sendgrid"
subcategory: ""
description: |-
Retrieve bounce settings for your SendGrid account.
Bounce settings allow you to configure how long soft bounces are retained in your suppression list. Soft bounces are temporary delivery failures, such as a full mailbox or temporary server issues.
The Soft Bounces setting specifies the number of days soft bounces will be kept in your soft bounces suppression list. Any soft bounces older than this value will be purged.
For more information, see the SendGrid Mail Settings Guide https://support.sendgrid.com/hc/en-us/articles/9489871931803-Mail-Settings-Guide-within-a-SendGrid-Account.
---

# sendgrid_bounce_settings (Data Source)

Retrieve bounce settings for your SendGrid account.

Bounce settings allow you to configure how long soft bounces are retained in your suppression list.
Soft bounces are temporary delivery failures, such as a full mailbox or temporary server issues.

The Soft Bounces setting specifies the number of days soft bounces will be kept in your soft bounces suppression list.
Any soft bounces older than this value will be purged.

For more information, see the [SendGrid Mail Settings Guide](https://support.sendgrid.com/hc/en-us/articles/9489871931803-Mail-Settings-Guide-within-a-SendGrid-Account).

## Example Usage

```terraform
data "sendgrid_bounce_settings" "example" {}

output "soft_bounce_purge_days" {
value = data.sendgrid_bounce_settings.example.soft_bounce_purge_days
}
```

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

### Read-Only

- `soft_bounce_purge_days` (Number) The number of days soft bounces will be kept in your soft bounces suppression list. Any soft bounces older than this value will be purged.
47 changes: 47 additions & 0 deletions docs/resources/bounce_settings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "sendgrid_bounce_settings Resource - terraform-provider-sendgrid"
subcategory: ""
description: |-
Manage bounce settings for your SendGrid account.
Bounce settings allow you to configure how long soft bounces are retained in your suppression list. Soft bounces are temporary delivery failures, such as a full mailbox or temporary server issues.
The Soft Bounces setting specifies the number of days soft bounces will be kept in your soft bounces suppression list. Any soft bounces older than this value will be purged.
For more information, see the SendGrid Mail Settings Guide https://support.sendgrid.com/hc/en-us/articles/9489871931803-Mail-Settings-Guide-within-a-SendGrid-Account.
---

# sendgrid_bounce_settings (Resource)

Manage bounce settings for your SendGrid account.

Bounce settings allow you to configure how long soft bounces are retained in your suppression list.
Soft bounces are temporary delivery failures, such as a full mailbox or temporary server issues.

The Soft Bounces setting specifies the number of days soft bounces will be kept in your soft bounces suppression list.
Any soft bounces older than this value will be purged.

For more information, see the [SendGrid Mail Settings Guide](https://support.sendgrid.com/hc/en-us/articles/9489871931803-Mail-Settings-Guide-within-a-SendGrid-Account).

## Example Usage

```terraform
resource "sendgrid_bounce_settings" "example" {
soft_bounce_purge_days = 30
}
```

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

### Optional

- `soft_bounce_purge_days` (Number) The number of days soft bounces will be kept in your soft bounces suppression list. Any soft bounces older than this value will be purged. Must be between 1 and 3650 days.

## Import

Import is supported using the following syntax:

The [`terraform import` command](https://developer.hashicorp.com/terraform/cli/commands/import) can be used, for example:

```shell
% terraform import sendgrid_bounce_settings.example ""
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
data "sendgrid_bounce_settings" "example" {}

output "soft_bounce_purge_days" {
value = data.sendgrid_bounce_settings.example.soft_bounce_purge_days
}
3 changes: 3 additions & 0 deletions examples/resources/sendgrid_bounce_settings/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "sendgrid_bounce_settings" "example" {
soft_bounce_purge_days = 30
}
149 changes: 149 additions & 0 deletions internal/provider/bounce_settings_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package provider

import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"time"

"github.com/kenzo0107/sendgrid"
)

// InputUpdateBounceSettings represents the request body for updating bounce settings
type InputUpdateBounceSettings struct {
SoftBouncePurgeDays int64 `json:"soft_bounces,omitempty"`
}

// OutputUpdateBounceSettings represents the response from updating bounce settings
type OutputUpdateBounceSettings struct {
SoftBouncePurgeDays int64 `json:"soft_bounces"`
}

// OutputGetBounceSettings represents the response from getting bounce settings
type OutputGetBounceSettings struct {
SoftBouncePurgeDays int64 `json:"soft_bounces"`
}

// BounceSettingsClient extends the SendGrid client with bounce settings methods
type BounceSettingsClient struct {
*sendgrid.Client
baseURL string
apiKey string
}

// NewBounceSettingsClient creates a new client with bounce settings methods
func NewBounceSettingsClient(client *sendgrid.Client, apiKey string) *BounceSettingsClient {
return &BounceSettingsClient{
Client: client,
baseURL: "https://api.sendgrid.com/v3",
apiKey: apiKey,
}
}

// makeRequest makes an HTTP request to the SendGrid API
func (c *BounceSettingsClient) makeRequest(ctx context.Context, method, path string, body interface{}) (*http.Response, error) {
var reqBody []byte
var err error

if body != nil {
reqBody, err = json.Marshal(body)
if err != nil {
return nil, fmt.Errorf("failed to marshal request body: %w", err)
}
}

url := c.baseURL + path
req, err := http.NewRequestWithContext(ctx, method, url, bytes.NewBuffer(reqBody))
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}

req.Header.Set("Authorization", "Bearer "+c.apiKey)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("User-Agent", "terraform-provider-sendgrid")

client := &http.Client{
Timeout: 30 * time.Second,
}

resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("failed to make request: %w", err)
}

return resp, nil
}

// GetBounceSettings retrieves the current bounce settings
func (c *BounceSettingsClient) GetBounceSettings(ctx context.Context) (*OutputGetBounceSettings, error) {
resp, err := c.makeRequest(ctx, http.MethodGet, "/mail_settings/bounce_purge", nil)
if err != nil {
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode == http.StatusNotFound {
// If the endpoint doesn't exist or returns 404, return default values
return &OutputGetBounceSettings{
SoftBouncePurgeDays: 7, // Default to 7 days
}, nil
}

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}

var result OutputGetBounceSettings
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, fmt.Errorf("failed to decode response: %w", err)
}

return &result, nil
}

// UpdateBounceSettings updates the bounce settings
func (c *BounceSettingsClient) UpdateBounceSettings(ctx context.Context, input *InputUpdateBounceSettings) (*OutputUpdateBounceSettings, error) {
resp, err := c.makeRequest(ctx, http.MethodPatch, "/mail_settings/bounce_purge", input)
if err != nil {
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode == http.StatusNotFound {
// If the endpoint doesn't exist, return the input as if it was set
return &OutputUpdateBounceSettings{
SoftBouncePurgeDays: input.SoftBouncePurgeDays,
}, nil
}

if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}

var result OutputUpdateBounceSettings
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, fmt.Errorf("failed to decode response: %w", err)
}

return &result, nil
}

// ExtendClient extends a SendGrid client with bounce settings methods
func ExtendClient(client *sendgrid.Client, apiKey string) ClientWithBounceSettings {
return &BounceSettingsClient{
Client: client,
baseURL: "https://api.sendgrid.com/v3",
apiKey: apiKey,
}
}

// ClientWithBounceSettings interface includes bounce settings methods
type ClientWithBounceSettings interface {
GetBounceSettings(ctx context.Context) (*OutputGetBounceSettings, error)
UpdateBounceSettings(ctx context.Context, input *InputUpdateBounceSettings) (*OutputUpdateBounceSettings, error)
}
126 changes: 126 additions & 0 deletions internal/provider/bounce_settings_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package provider

import (
"context"
"fmt"
"os"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/kenzo0107/sendgrid"
)

// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &bounceSettingsDataSource{}
_ datasource.DataSourceWithConfigure = &bounceSettingsDataSource{}
)

func newBounceSettingsDataSource() datasource.DataSource {
return &bounceSettingsDataSource{}
}

type bounceSettingsDataSource struct {
client *sendgrid.Client
extendedClient ClientWithBounceSettings
}

type bounceSettingsDataSourceModel struct {
SoftBouncePurgeDays types.Int64 `tfsdk:"soft_bounce_purge_days"`
}

func (d *bounceSettingsDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_bounce_settings"
}

func (d *bounceSettingsDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
// Prevent panic if the provider has not been configured.
if req.ProviderData == nil {
return
}

client, ok := req.ProviderData.(*sendgrid.Client)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *sendgrid.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)
return
}

d.client = client

// Get API key from environment for extended functionality
apiKey := os.Getenv("SENDGRID_API_KEY")
if apiKey == "" {
resp.Diagnostics.AddError(
"Missing SendGrid API Key",
"The bounce settings data source requires the SENDGRID_API_KEY environment variable to be set.",
)
return
}

d.extendedClient = ExtendClient(client, apiKey)
}

func (d *bounceSettingsDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: `
Retrieve bounce settings for your SendGrid account.

Bounce settings allow you to configure how long soft bounces are retained in your suppression list.
Soft bounces are temporary delivery failures, such as a full mailbox or temporary server issues.

The Soft Bounces setting specifies the number of days soft bounces will be kept in your soft bounces suppression list.
Any soft bounces older than this value will be purged.

For more information, see the [SendGrid Mail Settings Guide](https://support.sendgrid.com/hc/en-us/articles/9489871931803-Mail-Settings-Guide-within-a-SendGrid-Account).
`,
Attributes: map[string]schema.Attribute{
"soft_bounce_purge_days": schema.Int64Attribute{
MarkdownDescription: "The number of days soft bounces will be kept in your soft bounces suppression list. Any soft bounces older than this value will be purged.",
Computed: true,
},
},
}
}

func (d *bounceSettingsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var state bounceSettingsDataSourceModel

resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}

res, err := retryOnRateLimit(ctx, func() (interface{}, error) {
return d.extendedClient.GetBounceSettings(ctx)
})
if err != nil {
resp.Diagnostics.AddError(
"Reading bounce settings",
fmt.Sprintf("Unable to get bounce settings, got error: %s", err),
)
return
}

o, ok := res.(*OutputGetBounceSettings)
if !ok {
resp.Diagnostics.AddError(
"Reading bounce settings",
"Failed to assert type *OutputGetBounceSettings",
)
return
}

state.SoftBouncePurgeDays = types.Int64Value(o.SoftBouncePurgeDays)

resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}
}
Loading