Skip to content

Commit

Permalink
feat: Convert alert datasource to new sdk (#2020)
Browse files Browse the repository at this point in the history
* convert alert datasources to new sdk

* move auxiliary functions

* gofump

* add logs

* changes after review

* fixes

---------

Co-authored-by: Scott Winkler <scott.winkler@snowflake.com>
  • Loading branch information
sfc-gh-pbosak and sfc-gh-swinkler committed Sep 7, 2023
1 parent 43277a4 commit 2d0eaeb
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 363 deletions.
37 changes: 21 additions & 16 deletions pkg/datasources/alerts.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package datasources

import (
"context"
"database/sql"
"errors"
"log"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/snowflake"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"

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

Expand Down Expand Up @@ -82,27 +83,31 @@ func Alerts() *schema.Resource {
// ReadAlerts Reads the database metadata information.
func ReadAlerts(d *schema.ResourceData, meta interface{}) error {
db := meta.(*sql.DB)
client := sdk.NewClientFromDB(db)
ctx := context.Background()

d.SetId("alerts_read")
databaseName := d.Get("database").(string)
schemaName := d.Get("schema").(string)
alertPattern := d.Get("pattern").(string)

listAlerts, err := snowflake.ListAlerts(databaseName, schemaName, alertPattern, db)
if errors.Is(err, sql.ErrNoRows) {
log.Printf("[DEBUG] no alerts found in account (%s)", d.Id())
d.SetId("")
return nil
} else if err != nil {
log.Println("[DEBUG] failed to list alerts")
var like sdk.Like
if alertPattern != "" {
like = sdk.Like{Pattern: &alertPattern}
}
listAlerts, err := client.Alerts.Show(ctx, &sdk.ShowAlertOptions{
In: &sdk.In{
Schema: sdk.NewDatabaseObjectIdentifier(databaseName, schemaName),
},
Like: &like,
})
if err != nil {
log.Printf("[DEBUG] failed to list alerts in schema (%s)", d.Id())
d.SetId("")
return nil
return err
}

log.Printf("[DEBUG] list alerts: %v", listAlerts)

alerts := []map[string]interface{}{}
alerts := make([]map[string]any, 0, len(listAlerts))
for _, alert := range listAlerts {
alertMap := map[string]interface{}{}
alertMap := map[string]any{}
alertMap["name"] = alert.Name
alertMap["comment"] = alert.Comment
alertMap["owner"] = alert.Owner
Expand Down
18 changes: 18 additions & 0 deletions pkg/helpers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package helpers

import (
"fmt"
"log"
"reflect"
"regexp"
"strconv"
"strings"
"time"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
)
Expand Down Expand Up @@ -98,4 +100,20 @@ func DecodeSnowflakeID(id string) sdk.ObjectIdentifier {
}
}

func Retry(attempts int, sleepDuration time.Duration, f func() (error, bool)) error {
for i := 0; i < attempts; i++ {
err, done := f()
if err != nil {
return err
}
if done {
return nil
} else {
log.Printf("[INFO] operation not finished yet, retrying in %v seconds\n", sleepDuration.Seconds())
time.Sleep(sleepDuration)
}
}
return fmt.Errorf("giving up after %v attempts", attempts)
}

const IDDelimiter = "|"
40 changes: 36 additions & 4 deletions pkg/resources/alert.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import (
"log"
"strconv"
"strings"
"time"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/snowflake"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

Expand Down Expand Up @@ -282,7 +282,7 @@ func UpdateAlert(d *schema.ResourceData, meta interface{}) error {

enabled := d.Get("enabled").(bool)
if d.HasChanges("enabled", "warehouse", "alert_schedule", "condition", "action", "comment") {
if err := snowflake.WaitSuspendAlert(ctx, client, objectIdentifier); err != nil {
if err := waitSuspendAlert(ctx, client, objectIdentifier); err != nil {
log.Printf("[WARN] failed to suspend alert %s", objectIdentifier.Name())
}
}
Expand Down Expand Up @@ -344,11 +344,11 @@ func UpdateAlert(d *schema.ResourceData, meta interface{}) error {
}

if enabled {
if err := snowflake.WaitResumeAlert(ctx, client, objectIdentifier); err != nil {
if err := waitResumeAlert(ctx, client, objectIdentifier); err != nil {
log.Printf("[WARN] failed to resume alert %s", objectIdentifier.Name())
}
} else {
if err := snowflake.WaitSuspendAlert(ctx, client, objectIdentifier); err != nil {
if err := waitSuspendAlert(ctx, client, objectIdentifier); err != nil {
log.Printf("[WARN] failed to suspend alert %s", objectIdentifier.Name())
}
}
Expand All @@ -370,3 +370,35 @@ func DeleteAlert(d *schema.ResourceData, meta interface{}) error {
d.SetId("")
return nil
}

func waitResumeAlert(ctx context.Context, client *sdk.Client, id sdk.SchemaObjectIdentifier) error {
resumeAlert := func() (error, bool) {
opts := sdk.AlterAlertOptions{Action: &sdk.AlertActionResume}
err := client.Alerts.Alter(ctx, id, &opts)
if err != nil {
return fmt.Errorf("error resuming alert %v err = %w", id.Name(), err), false
}
alert, err := client.Alerts.ShowByID(ctx, id)
if err != nil {
return err, false
}
return nil, alert.State == sdk.AlertStateStarted
}
return helpers.Retry(5, 10*time.Second, resumeAlert)
}

func waitSuspendAlert(ctx context.Context, client *sdk.Client, id sdk.SchemaObjectIdentifier) error {
suspendAlert := func() (error, bool) {
opts := sdk.AlterAlertOptions{Action: &sdk.AlertActionSuspend}
err := client.Alerts.Alter(ctx, id, &opts)
if err != nil {
return fmt.Errorf("error suspending alert %v err = %w", id.Name(), err), false
}
alert, err := client.Alerts.ShowByID(ctx, id)
if err != nil {
return err, false
}
return nil, alert.State == sdk.AlertStateSuspended
}
return helpers.Retry(5, 10*time.Second, suspendAlert)
}

0 comments on commit 2d0eaeb

Please sign in to comment.