From e9f0cb6f57b2eafd60822ee3dcc6527792f55d76 Mon Sep 17 00:00:00 2001 From: andybeeswax <48691060+andybeeswax@users.noreply.github.com> Date: Tue, 13 Oct 2020 13:36:35 -0400 Subject: [PATCH] change credit quota to float on read, int on write (#274) Snowflake only accepts credit_quota as an int. However, the `show resource monitors` command returns it as a float. This PR converts the float read from Snowflake into an int. ## Test Plan * [x] acceptance tests ## References Fixes https://github.com/chanzuckerberg/terraform-provider-snowflake/issues/145 and https://github.com/chanzuckerberg/terraform-provider-snowflake/issues/109 --- docs/resources/resource_monitor.md | 2 +- pkg/resources/resource_monitor.go | 23 ++++++++------- .../resource_monitor_acceptance_test.go | 2 ++ pkg/resources/resource_monitor_test.go | 6 ++-- pkg/snowflake/resource_monitor.go | 28 +++++++++---------- pkg/snowflake/resource_monitor_test.go | 13 +++------ 6 files changed, 37 insertions(+), 37 deletions(-) diff --git a/docs/resources/resource_monitor.md b/docs/resources/resource_monitor.md index 38c1e715886..9470035c74b 100644 --- a/docs/resources/resource_monitor.md +++ b/docs/resources/resource_monitor.md @@ -7,7 +7,7 @@ | NAME | TYPE | DESCRIPTION | OPTIONAL | REQUIRED | COMPUTED | DEFAULT | |----------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------|----------|-----------|----------|---------| -| credit_quota | float | The amount of credits allocated monthly to the resource monitor, round up to 2 decimal places. | true | false | true | | +| credit_quota | int | The number of credits allocated monthly to the resource monitor. | true | false | true | | | end_timestamp | string | The date and time when the resource monitor suspends the assigned warehouses. | true | false | false | | | frequency | string | The frequency interval at which the credit usage resets to 0. If you set a frequency for a resource monitor, you must also set START_TIMESTAMP. | true | false | true | | | name | string | Identifier for the resource monitor; must be unique for your account. | false | true | false | | diff --git a/pkg/resources/resource_monitor.go b/pkg/resources/resource_monitor.go index 5e3b3cbddbe..804e00ca33a 100644 --- a/pkg/resources/resource_monitor.go +++ b/pkg/resources/resource_monitor.go @@ -22,10 +22,10 @@ var resourceMonitorSchema = map[string]*schema.Schema{ ForceNew: true, }, "credit_quota": { - Type: schema.TypeFloat, + Type: schema.TypeInt, Optional: true, Computed: true, - Description: "The amount of credits allocated monthly to the resource monitor, round up to 2 decimal places.", + Description: "The number of credits allocated monthly to the resource monitor.", ForceNew: true, }, "frequency": { @@ -96,7 +96,7 @@ func CreateResourceMonitor(data *schema.ResourceData, meta interface{}) error { cb := snowflake.ResourceMonitor(name).Create() // Set optionals if v, ok := data.GetOk("credit_quota"); ok { - cb.SetFloat("credit_quota", v.(float64)) + cb.SetInt("credit_quota", v.(int)) } if v, ok := data.GetOk("frequency"); ok { cb.SetString("frequency", v.(string)) @@ -157,14 +157,17 @@ func ReadResourceMonitor(data *schema.ResourceData, meta interface{}) error { return err } - // Credit quota is a float + // Snowflake returns credit_quota as a float, but only accepts input as an int if rm.CreditQuota.Valid { - err = data.Set("credit_quota", rm.CreditQuota.Float64) - } else { - err = data.Set("credit_quota", 0.0) // not sure if this is the right approach - } - if err != nil { - return err + cqf, err := strconv.ParseFloat(rm.CreditQuota.String, 64) + if err != nil { + return err + } + + err = data.Set("credit_quota", int(cqf)) + if err != nil { + return err + } } // Triggers diff --git a/pkg/resources/resource_monitor_acceptance_test.go b/pkg/resources/resource_monitor_acceptance_test.go index 87fdc770243..77a97c2ab9c 100644 --- a/pkg/resources/resource_monitor_acceptance_test.go +++ b/pkg/resources/resource_monitor_acceptance_test.go @@ -19,6 +19,7 @@ func TestAccResourceMonitor(t *testing.T) { Config: resourceMonitorConfig(name), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("snowflake_resource_monitor.test", "name", name), + resource.TestCheckResourceAttr("snowflake_resource_monitor.test", "credit_quota", "100"), ), }, // IMPORT @@ -35,6 +36,7 @@ func resourceMonitorConfig(accName string) string { return fmt.Sprintf(` resource "snowflake_resource_monitor" "test" { name = "%v" + credit_quota = 100 } `, accName) } diff --git a/pkg/resources/resource_monitor_test.go b/pkg/resources/resource_monitor_test.go index 689f8d4b30e..f047668f542 100644 --- a/pkg/resources/resource_monitor_test.go +++ b/pkg/resources/resource_monitor_test.go @@ -24,7 +24,7 @@ func TestResourceMonitorCreate(t *testing.T) { in := map[string]interface{}{ "name": "good_name", - "credit_quota": 100.00, + "credit_quota": 100, "notify_triggers": []interface{}{75, 88}, "suspend_triggers": []interface{}{99}, "suspend_immediate_triggers": []interface{}{105}, @@ -35,7 +35,7 @@ func TestResourceMonitorCreate(t *testing.T) { WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) { mock.ExpectExec( - `^CREATE RESOURCE MONITOR "good_name" CREDIT_QUOTA=100.00 TRIGGERS ON 99 PERCENT DO SUSPEND ON 105 PERCENT DO SUSPEND_IMMEDIATE ON 88 PERCENT DO NOTIFY ON 75 PERCENT DO NOTIFY$`, + `^CREATE RESOURCE MONITOR "good_name" CREDIT_QUOTA=100 TRIGGERS ON 99 PERCENT DO SUSPEND ON 105 PERCENT DO SUSPEND_IMMEDIATE ON 88 PERCENT DO NOTIFY ON 75 PERCENT DO NOTIFY$`, ).WillReturnResult(sqlmock.NewResult(1, 1)) expectReadResourceMonitor(mock) @@ -50,7 +50,7 @@ func expectReadResourceMonitor(mock sqlmock.Sqlmock) { "frequency", "start_time", "end_time", "notify_at", "suspend_at", "suspend_immediately_at", "created_on", "owner", "comment", }).AddRow( - "good_name", 100.00, 0, 100, "", "MONTHLY", "2001-01-01 00:00:00.000 -0700", + "good_name", 100.00, 0.00, 100.00, "", "MONTHLY", "2001-01-01 00:00:00.000 -0700", "", "75%,88%", "99%", "105%", "2001-01-01 00:00:00.000 -0700", "ACCOUNTADMIN", "") mock.ExpectQuery(`^SHOW RESOURCE MONITORS LIKE 'good_name'$`).WillReturnRows(rows) } diff --git a/pkg/snowflake/resource_monitor.go b/pkg/snowflake/resource_monitor.go index 21c08371402..aa7d155acd4 100644 --- a/pkg/snowflake/resource_monitor.go +++ b/pkg/snowflake/resource_monitor.go @@ -118,20 +118,20 @@ func (rcb *ResourceMonitorCreateBuilder) Statement() string { } type resourceMonitor struct { - Name sql.NullString `db:"name"` - CreditQuota sql.NullFloat64 `db:"credit_quota"` - UsedCredits sql.NullString `db:"used_credits"` - RemainingCredits sql.NullString `db:"remaining_credits"` - Level sql.NullString `db:"level"` - Frequency sql.NullString `db:"frequency"` - StartTime sql.NullString `db:"start_time"` - EndTime sql.NullString `db:"end_time"` - NotifyAt sql.NullString `db:"notify_at"` - SuspendAt sql.NullString `db:"suspend_at"` - SuspendImmediatelyAt sql.NullString `db:"suspend_immediately_at"` - CreatedOn sql.NullString `db:"created_on"` - Owner sql.NullString `db:"owner"` - Comment sql.NullString `db:"comment"` + Name sql.NullString `db:"name"` + CreditQuota sql.NullString `db:"credit_quota"` + UsedCredits sql.NullString `db:"used_credits"` + RemainingCredits sql.NullString `db:"remaining_credits"` + Level sql.NullString `db:"level"` + Frequency sql.NullString `db:"frequency"` + StartTime sql.NullString `db:"start_time"` + EndTime sql.NullString `db:"end_time"` + NotifyAt sql.NullString `db:"notify_at"` + SuspendAt sql.NullString `db:"suspend_at"` + SuspendImmediatelyAt sql.NullString `db:"suspend_immediately_at"` + CreatedOn sql.NullString `db:"created_on"` + Owner sql.NullString `db:"owner"` + Comment sql.NullString `db:"comment"` } func ScanResourceMonitor(row *sqlx.Row) (*resourceMonitor, error) { diff --git a/pkg/snowflake/resource_monitor_test.go b/pkg/snowflake/resource_monitor_test.go index 9bbe41ea26e..04eb4c16ab0 100644 --- a/pkg/snowflake/resource_monitor_test.go +++ b/pkg/snowflake/resource_monitor_test.go @@ -22,20 +22,15 @@ func TestResourceMonitor(t *testing.T) { r.Equal(`DROP RESOURCE MONITOR "resource_monitor"`, q) ab := rm.Alter() - ab.SetFloat("credit_quota", 66.6) + ab.SetInt("credit_quota", 66) q = ab.Statement() - r.Equal(`ALTER RESOURCE MONITOR "resource_monitor" SET CREDIT_QUOTA=66.60`, q) + r.Equal(`ALTER RESOURCE MONITOR "resource_monitor" SET CREDIT_QUOTA=66`, q) cb := snowflake.ResourceMonitor("resource_monitor").Create() cb.NotifyAt(80).NotifyAt(90).SuspendAt(95).SuspendImmediatelyAt(100) cb.SetString("frequency", "YEARLY") - cb.SetFloat("credit_quota", 666.66666666) + cb.SetInt("credit_quota", 666) q = cb.Statement() - r.Equal(`CREATE RESOURCE MONITOR "resource_monitor" FREQUENCY='YEARLY' CREDIT_QUOTA=666.67 TRIGGERS ON 80 PERCENT DO NOTIFY ON 90 PERCENT DO NOTIFY ON 95 PERCENT DO SUSPEND ON 100 PERCENT DO SUSPEND_IMMEDIATE`, q) - - // Check if credit quota can be parsed correctly to float if given an integer - cb.SetFloat("credit_quota", 666) - q = cb.Statement() - r.Equal(`CREATE RESOURCE MONITOR "resource_monitor" FREQUENCY='YEARLY' CREDIT_QUOTA=666.00 TRIGGERS ON 80 PERCENT DO NOTIFY ON 90 PERCENT DO NOTIFY ON 95 PERCENT DO SUSPEND ON 100 PERCENT DO SUSPEND_IMMEDIATE`, q) + r.Equal(`CREATE RESOURCE MONITOR "resource_monitor" FREQUENCY='YEARLY' CREDIT_QUOTA=666 TRIGGERS ON 80 PERCENT DO NOTIFY ON 90 PERCENT DO NOTIFY ON 95 PERCENT DO SUSPEND ON 100 PERCENT DO SUSPEND_IMMEDIATE`, q) }