From 0cdcc79431e6a1ace8be07d1c48a75788866eaec Mon Sep 17 00:00:00 2001 From: israel Date: Sun, 24 Jul 2022 14:04:22 +0300 Subject: [PATCH 1/3] Added a generic "resource not found error" Fixed 'function' not exist scenario Fixed grant helpers to consider only relevant grants --- pkg/resources/function.go | 7 +++++-- pkg/resources/grant_helpers.go | 29 +++++++++++++++++++++++------ pkg/resources/user.go | 8 +------- pkg/snowflake/errors.go | 12 ++++++++++++ 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/pkg/resources/function.go b/pkg/resources/function.go index 96fff149ec..b29059c36c 100644 --- a/pkg/resources/function.go +++ b/pkg/resources/function.go @@ -272,8 +272,11 @@ func ReadFunction(d *schema.ResourceData, meta interface{}) error { return err } rows, err := snowflake.Query(db, stmt) - if err != nil { - return err + if err != nil && snowflake.IsResourceNotExistOrNotAuthorized(err.Error(), "Function") { + // If not found, mark resource to be removed from statefile during apply or refresh + log.Printf("[DEBUG] function (%s) not found or we are not authorized.Err:\n%s", d.Id(), err.Error()) + d.SetId("") + return nil } defer rows.Close() descPropValues, err := snowflake.ScanFunctionDescription(rows) diff --git a/pkg/resources/grant_helpers.go b/pkg/resources/grant_helpers.go index e164c1b19d..721187c293 100644 --- a/pkg/resources/grant_helpers.go +++ b/pkg/resources/grant_helpers.go @@ -5,16 +5,15 @@ import ( "database/sql" "encoding/csv" "fmt" - "log" - "regexp" - "strings" - "time" - "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/snowflake" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/jmoiron/sqlx" "github.com/pkg/errors" "github.com/snowflakedb/gosnowflake" + "log" + "regexp" + "strings" + "time" ) // TerraformGrantResource augments terraform's *schema.Resource with extra context @@ -229,15 +228,29 @@ func readGenericGrant( } return err } + priv := d.Get("privilege").(string) grantOption := d.Get("with_grant_option").(bool) + var relevantGrants []*grant + for _, grant := range grants { + if grant.Privilege == priv && grant.GrantOption == grantOption { + relevantGrants = append(relevantGrants, grant) + } + } + + // If no relevant grants, set id to blank and return (see HACK HACK comment above) + if len(relevantGrants) == 0 { + d.SetId("") + return nil + } + // Map of roles to privileges rolePrivileges := map[string]PrivilegeSet{} sharePrivileges := map[string]PrivilegeSet{} // List of all grants for each schema_database - for _, grant := range grants { + for _, grant := range relevantGrants { switch grant.GranteeType { case "ROLE": roleName := grant.GranteeName @@ -312,6 +325,10 @@ func readGenericGrant( if err != nil { return err } + log.Printf("[DEBUG] integration_name: %v", d.Get("integration_name")) + log.Printf("[DEBUG] privilege: %v", d.Get("privilege")) + log.Printf("[DEBUG] with_grant_option: %v", d.Get("with_grant_option")) + log.Printf("[DEBUG] enable_multiple_grants: %v", d.Get("enable_multiple_grants")) return nil } diff --git a/pkg/resources/user.go b/pkg/resources/user.go index 8afd6c72fb..40bc2d50d6 100644 --- a/pkg/resources/user.go +++ b/pkg/resources/user.go @@ -3,7 +3,6 @@ package resources import ( "database/sql" "log" - "regexp" "strings" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/snowflake" @@ -140,11 +139,6 @@ var userSchema = map[string]*schema.Schema{ // MINS_TO_BYPASS_NETWORK POLICY = } -func isUserNotExistOrNotAuthorized(errorString string) bool { - var userNotExistOrNotAuthorizedRegEx, _ = regexp.Compile("SQL compilation error:User '.*' does not exist or not authorized.") - return userNotExistOrNotAuthorizedRegEx.MatchString(strings.ReplaceAll(errorString, "\n", "")) -} - func User() *schema.Resource { return &schema.Resource{ Create: CreateUser, @@ -174,7 +168,7 @@ func ReadUser(d *schema.ResourceData, meta interface{}) error { stmt := snowflake.User(id).Describe() rows, err := snowflake.Query(db, stmt) - if err != nil && isUserNotExistOrNotAuthorized(err.Error()) { + if err != nil && snowflake.IsResourceNotExistOrNotAuthorized(err.Error(), "User") { // If not found, mark resource to be removed from statefile during apply or refresh log.Printf("[DEBUG] user (%s) not found or we are not authorized.Err:\n%s", d.Id(), err.Error()) d.SetId("") diff --git a/pkg/snowflake/errors.go b/pkg/snowflake/errors.go index 5147876bab..f9c4e802b8 100644 --- a/pkg/snowflake/errors.go +++ b/pkg/snowflake/errors.go @@ -1,6 +1,18 @@ package snowflake +import ( + "fmt" + "regexp" + "strings" +) + // Generic Errors var ( ErrNoRowInRS = "sql: no rows in result set" ) + +func IsResourceNotExistOrNotAuthorized(errorString string, resourceType string) bool { + regexStr := fmt.Sprintf("SQL compilation error:%s '.*' does not exist or not authorized.", resourceType) + var userNotExistOrNotAuthorizedRegEx, _ = regexp.Compile(regexStr) + return userNotExistOrNotAuthorizedRegEx.MatchString(strings.ReplaceAll(errorString, "\n", "")) +} From a95879ddd19a6fbbbc54d1d2721e1978abfa2439 Mon Sep 17 00:00:00 2001 From: israel Date: Tue, 2 Aug 2022 11:28:08 +0300 Subject: [PATCH 2/3] Added a generic "resource not found error" Fixed 'function' not exist scenario Fixed grant helpers to consider only relevant grants Fixed 'stage' not exist scenario --- pkg/resources/grant_helpers.go | 9 +++++---- pkg/resources/stage.go | 15 ++++++++------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/pkg/resources/grant_helpers.go b/pkg/resources/grant_helpers.go index 721187c293..c423e9a08a 100644 --- a/pkg/resources/grant_helpers.go +++ b/pkg/resources/grant_helpers.go @@ -5,15 +5,16 @@ import ( "database/sql" "encoding/csv" "fmt" + "log" + "regexp" + "strings" + "time" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/snowflake" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/jmoiron/sqlx" "github.com/pkg/errors" "github.com/snowflakedb/gosnowflake" - "log" - "regexp" - "strings" - "time" ) // TerraformGrantResource augments terraform's *schema.Resource with extra context diff --git a/pkg/resources/stage.go b/pkg/resources/stage.go index 4b407827f1..23ee32c75a 100644 --- a/pkg/resources/stage.go +++ b/pkg/resources/stage.go @@ -235,14 +235,15 @@ func ReadStage(d *schema.ResourceData, meta interface{}) error { q := snowflake.Stage(stage, dbName, schema).Describe() stageDesc, err := snowflake.DescStage(db, q) - if err == sql.ErrNoRows { - // If not found, mark resource to be removed from statefile during apply or refresh - log.Printf("[DEBUG] stage (%s) not found", d.Id()) - d.SetId("") - return nil - } if err != nil { - return err + if snowflake.IsResourceNotExistOrNotAuthorized(err.Error(), "Stage") { + // If not found, mark resource to be removed from state file during apply or refresh + log.Printf("[DEBUG] stage (%s) not found or we are not authorized.Err:\n%s", d.Id(), err.Error()) + d.SetId("") + return nil + } else { + return err + } } sq := snowflake.Stage(stage, dbName, schema).Show() From 412e14b0672074f63ab9d16a2c3d2ca1c14b6192 Mon Sep 17 00:00:00 2001 From: Israel Klein Date: Sun, 11 Sep 2022 17:34:47 +0300 Subject: [PATCH 3/3] Added a generic "resource not found error" Fixed 'function' not exist scenario Fixed grant helpers to consider only relevant grants Fixed 'stage' not exist scenario removed unnecessary debug logs --- pkg/resources/grant_helpers.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pkg/resources/grant_helpers.go b/pkg/resources/grant_helpers.go index c423e9a08a..8ba013bd05 100644 --- a/pkg/resources/grant_helpers.go +++ b/pkg/resources/grant_helpers.go @@ -240,7 +240,7 @@ func readGenericGrant( } } - // If no relevant grants, set id to blank and return (see HACK HACK comment above) + // If no relevant grants, set id to blank and return if len(relevantGrants) == 0 { d.SetId("") return nil @@ -287,6 +287,7 @@ func readGenericGrant( existingRoles := d.Get("roles").(*schema.Set) multipleGrantFeatureFlag := d.Get("enable_multiple_grants").(bool) var roles, shares []string + // Now see which roles have our privilege for roleName, privileges := range rolePrivileges { // Where priv is not all so it should match exactly @@ -326,10 +327,7 @@ func readGenericGrant( if err != nil { return err } - log.Printf("[DEBUG] integration_name: %v", d.Get("integration_name")) - log.Printf("[DEBUG] privilege: %v", d.Get("privilege")) - log.Printf("[DEBUG] with_grant_option: %v", d.Get("with_grant_option")) - log.Printf("[DEBUG] enable_multiple_grants: %v", d.Get("enable_multiple_grants")) + return nil }