Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add b2_bucket_notification_rules resource and data source #91

Merged
merged 3 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Infrastructure
* Use Python 3.13 for embedded pybindings
### Added
* Added support for Event Notifications via `b2_bucket_notification_rules` resource and data source

### Infrastructure
* Replace deprecated macos-12 with macos-13
* Use crazy-max/ghaction-import-gpg action as a replacement of deprecated paultyng/ghaction-import-gpg
* Use Python 3.13 for embedded pybindings

## [0.9.0] - 2024-10-20

Expand Down
2 changes: 1 addition & 1 deletion b2/bindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,6 @@ func GetBindings() (string, error) {
}

bindings = &destinationPath
log.Printf("[TRACE] Extracted pybindings: %s\n", *bindings)
log.Printf("Extracted pybindings: %s\n", *bindings)
return *bindings, nil
}
29 changes: 21 additions & 8 deletions b2/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ package b2

import (
"bytes"
"context"
"encoding/json"
"fmt"
"log"
"os"
"os/exec"

"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

Expand All @@ -42,9 +43,15 @@ type Client struct {
SensitiveResources map[string]map[string]bool
}

func (c Client) apply(name string, op string, input map[string]interface{}) (map[string]interface{}, error) {
log.Printf("[TRACE] Executing pybindings for '%s' and '%s' operation\n", name, op)
log.Printf("[TRACE] Input for pybindings: %+v\n", input)
func (c Client) apply(ctx context.Context, name string, op string, input map[string]interface{}) (map[string]interface{}, error) {
tflog.Info(ctx, "Executing pybindings", map[string]interface{}{
"name": name,
"op": op,
})

tflog.Debug(ctx, "Input for pybindings", map[string]interface{}{
"input": input,
})

cmd := exec.Command(c.Exec, name, op)
cmd.Env = os.Environ()
Expand All @@ -66,12 +73,16 @@ func (c Client) apply(name string, op string, input map[string]interface{}) (map
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
if exitErr.Stderr != nil && len(exitErr.Stderr) > 0 {
log.Printf("[ERROR] Error in pybindings: %+v\n", string(exitErr.Stderr))
tflog.Error(ctx, "Error in pybindings", map[string]interface{}{
"stderr": fmt.Errorf(string(exitErr.Stderr)),
})
return nil, fmt.Errorf(string(exitErr.Stderr))
}
return nil, fmt.Errorf("failed to execute")
} else {
log.Println(err)
tflog.Error(ctx, "Error", map[string]interface{}{
"err": err,
})
return nil, err
}
}
Expand Down Expand Up @@ -99,12 +110,14 @@ func (c Client) apply(name string, op string, input map[string]interface{}) (map
safeOutput[k] = v
}
}
log.Printf("[TRACE] Safe output from pybindings: %+v\n", safeOutput)
tflog.Debug(ctx, "Safe output from pybindings", map[string]interface{}{
"output": safeOutput,
})

return output, nil
}

func (c Client) populate(name string, op string, output map[string]interface{}, d *schema.ResourceData) error {
func (c Client) populate(ctx context.Context, name string, op string, output map[string]interface{}, d *schema.ResourceData) error {
resourceName := "b2_" + name
var schemaList []string
if op == DATA_SOURCE_READ {
Expand Down
4 changes: 2 additions & 2 deletions b2/data_source_b2_account_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@ func dataSourceB2AccountInfoRead(ctx context.Context, d *schema.ResourceData, me

input := map[string]interface{}{}

output, err := client.apply(name, op, input)
output, err := client.apply(ctx, name, op, input)
if err != nil {
return diag.FromErr(err)
}

d.SetId(output["account_id"].(string))

err = client.populate(name, op, output, d)
err = client.populate(ctx, name, op, output, d)
if err != nil {
return diag.FromErr(err)
}
Expand Down
4 changes: 2 additions & 2 deletions b2/data_source_b2_application_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@ func dataSourceB2ApplicationKeyRead(ctx context.Context, d *schema.ResourceData,
"key_name": d.Get("key_name").(string),
}

output, err := client.apply(name, op, input)
output, err := client.apply(ctx, name, op, input)
if err != nil {
return diag.FromErr(err)
}

d.SetId(output["application_key_id"].(string))

err = client.populate(name, op, output, d)
err = client.populate(ctx, name, op, output, d)
if err != nil {
return diag.FromErr(err)
}
Expand Down
4 changes: 2 additions & 2 deletions b2/data_source_b2_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,14 @@ func dataSourceB2BucketRead(ctx context.Context, d *schema.ResourceData, meta in
"bucket_name": d.Get("bucket_name").(string),
}

output, err := client.apply(name, op, input)
output, err := client.apply(ctx, name, op, input)
if err != nil {
return diag.FromErr(err)
}

d.SetId(output["bucket_id"].(string))

err = client.populate(name, op, output, d)
err = client.populate(ctx, name, op, output, d)
if err != nil {
return diag.FromErr(err)
}
Expand Down
4 changes: 2 additions & 2 deletions b2/data_source_b2_bucket_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@ func dataSourceB2BucketFileRead(ctx context.Context, d *schema.ResourceData, met
"show_versions": d.Get("show_versions").(bool),
}

output, err := client.apply(name, op, input)
output, err := client.apply(ctx, name, op, input)
if err != nil {
return diag.FromErr(err)
}

d.SetId(output["_sha1"].(string))

err = client.populate(name, op, output, d)
err = client.populate(ctx, name, op, output, d)
if err != nil {
return diag.FromErr(err)
}
Expand Down
4 changes: 2 additions & 2 deletions b2/data_source_b2_bucket_file_signed_url.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ func dataSourceB2BucketFileSignedUrlRead(ctx context.Context, d *schema.Resource
"duration": d.Get("duration").(int),
}

output, err := client.apply(name, op, input)
output, err := client.apply(ctx, name, op, input)
if err != nil {
return diag.FromErr(err)
}

d.SetId(output["signed_url"].(string))

err = client.populate(name, op, output, d)
err = client.populate(ctx, name, op, output, d)
if err != nil {
return diag.FromErr(err)
}
Expand Down
4 changes: 2 additions & 2 deletions b2/data_source_b2_bucket_files.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,14 @@ func dataSourceB2BucketFilesRead(ctx context.Context, d *schema.ResourceData, me
"recursive": d.Get("recursive").(bool),
}

output, err := client.apply(name, op, input)
output, err := client.apply(ctx, name, op, input)
if err != nil {
return diag.FromErr(err)
}

d.SetId(output["_sha1"].(string))

err = client.populate(name, op, output, d)
err = client.populate(ctx, name, op, output, d)
if err != nil {
return diag.FromErr(err)
}
Expand Down
66 changes: 66 additions & 0 deletions b2/data_source_b2_bucket_notification_rules.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//####################################################################
//
// File: b2/data_source_b2_bucket_notification_rules.go
//
// Copyright 2024 Backblaze Inc. All Rights Reserved.
//
// License https://www.backblaze.com/using_b2_code.html
//
//####################################################################

package b2

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

func dataSourceB2BucketNotificationRules() *schema.Resource {
return &schema.Resource{
Description: "B2 bucket notification rules data source.",

ReadContext: dataSourceB2BucketNotificationRulesRead,

Schema: map[string]*schema.Schema{
"bucket_id": {
Description: "The ID of the bucket.",
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.NoZeroValues,
},
"notification_rules": {
Description: "An array of Event Notification Rules.",
Type: schema.TypeList,
Elem: getNotificationRulesElem(true),
Computed: true,
},
},
}
}

func dataSourceB2BucketNotificationRulesRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*Client)
const name = "bucket_notification_rules"
const op = DATA_SOURCE_READ

input := map[string]interface{}{
"bucket_id": d.Get("bucket_id").(string),
}

output, err := client.apply(ctx, name, op, input)
if err != nil {
return diag.FromErr(err)
}

d.SetId(output["bucket_id"].(string))

err = client.populate(ctx, name, op, output, d)
if err != nil {
return diag.FromErr(err)
}

return nil
}
71 changes: 71 additions & 0 deletions b2/data_source_b2_bucket_notification_rules_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//####################################################################
//
// File: b2/data_source_b2_bucket_notification_rules_test.go
//
// Copyright 2024 Backblaze Inc. All Rights Reserved.
//
// License https://www.backblaze.com/using_b2_code.html
//
//####################################################################

package b2

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccDataSourceB2BucketNotificationRules_basic(t *testing.T) {
parentResourceName := "b2_bucket.test"
resourceName := "b2_bucket_notification_rules.test"
dataSourceName := "data.b2_bucket_notification_rules.test"

bucketName := acctest.RandomWithPrefix("test-b2-tfp")
ruleName := acctest.RandomWithPrefix("test-b2-tfp")

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: testAccDataSourceB2BucketNotificationRulesConfig_basic(bucketName, ruleName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "bucket_id", resourceName, "bucket_id"),
resource.TestCheckResourceAttrPair(dataSourceName, "bucket_id", parentResourceName, "bucket_id"),
resource.TestCheckResourceAttrPair(dataSourceName, "notification_rules", resourceName, "notification_rules"),
),
},
},
})
}

func testAccDataSourceB2BucketNotificationRulesConfig_basic(bucketName string, ruleName string) string {
return fmt.Sprintf(`
resource "b2_bucket" "test" {
bucket_name = "%s"
bucket_type = "allPublic"
}

resource "b2_bucket_notification_rules" "test" {
bucket_id = b2_bucket.test.id
notification_rules {
name = "%s"
event_types = ["b2:ObjectCreated:*"]
target_configuration {
target_type = "webhook"
url = "https://example.com/webhook"
}
}
}

data "b2_bucket_notification_rules" "test" {
bucket_id = b2_bucket.test.bucket_id
depends_on = [
b2_bucket_notification_rules.test,
]
}
`, bucketName, ruleName)
}
26 changes: 15 additions & 11 deletions b2/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ package b2
import (
"context"
"fmt"
"log"

"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
Expand Down Expand Up @@ -58,17 +58,19 @@ func New(version string, exec string) func() *schema.Provider {
},
},
DataSourcesMap: map[string]*schema.Resource{
"b2_account_info": dataSourceB2AccountInfo(),
"b2_application_key": dataSourceB2ApplicationKey(),
"b2_bucket": dataSourceB2Bucket(),
"b2_bucket_file": dataSourceB2BucketFile(),
"b2_bucket_file_signed_url": dataSourceB2BucketFileSignedUrl(),
"b2_bucket_files": dataSourceB2BucketFiles(),
"b2_account_info": dataSourceB2AccountInfo(),
"b2_application_key": dataSourceB2ApplicationKey(),
"b2_bucket": dataSourceB2Bucket(),
"b2_bucket_file": dataSourceB2BucketFile(),
"b2_bucket_file_signed_url": dataSourceB2BucketFileSignedUrl(),
"b2_bucket_files": dataSourceB2BucketFiles(),
"b2_bucket_notification_rules": dataSourceB2BucketNotificationRules(),
},
ResourcesMap: map[string]*schema.Resource{
"b2_application_key": resourceB2ApplicationKey(),
"b2_bucket": resourceB2Bucket(),
"b2_bucket_file_version": resourceB2BucketFileVersion(),
"b2_application_key": resourceB2ApplicationKey(),
"b2_bucket": resourceB2Bucket(),
"b2_bucket_file_version": resourceB2BucketFileVersion(),
"b2_bucket_notification_rules": resourceB2BucketNotificationRules(),
},
}

Expand Down Expand Up @@ -117,7 +119,9 @@ func configure(version string, exec string, p *schema.Provider) func(context.Con
SensitiveResources: sensitiveResources,
}

log.Printf("[DEBUG] User Agent append: %s\n", userAgent)
tflog.Info(ctx, "User Agent append", map[string]interface{}{
"user_agent_append": userAgent,
})

return client, nil
}
Expand Down
Loading
Loading