diff --git a/pkg/resources/api_integration.go b/pkg/resources/api_integration.go index 44d41deff1..e2f9cfaf7c 100644 --- a/pkg/resources/api_integration.go +++ b/pkg/resources/api_integration.go @@ -150,7 +150,13 @@ func ReadAPIIntegration(d *schema.ResourceData, meta interface{}) error { s, err := snowflake.ScanApiIntegration(row) if err != nil { - return fmt.Errorf("Could not show api integration: %w", err) + // If no such resource exists, it is not an error but rather not exist + if err.Error() == snowflake.ErrNoRowInRS { + d.SetId("") + return nil + } else { + return fmt.Errorf("Could not show api integration: %w", err) + } } // Note: category must be API or something is broken diff --git a/pkg/resources/external_function.go b/pkg/resources/external_function.go index 6122779734..4563fb6bc5 100644 --- a/pkg/resources/external_function.go +++ b/pkg/resources/external_function.go @@ -342,7 +342,12 @@ func ReadExternalFunction(d *schema.ResourceData, meta interface{}) error { row := snowflake.QueryRow(db, stmt) externalFunction, err := snowflake.ScanExternalFunction(row) if err != nil { - return err + if err.Error() == snowflake.ErrNoRowInRS { + d.SetId("") + return nil + } else { + return err + } } // Note: 'language' must be EXTERNAL and 'is_external_function' set to Y diff --git a/pkg/resources/external_table.go b/pkg/resources/external_table.go index d3c9d00e47..2871749204 100644 --- a/pkg/resources/external_table.go +++ b/pkg/resources/external_table.go @@ -275,7 +275,13 @@ func ReadExternalTable(d *schema.ResourceData, meta interface{}) error { row := snowflake.QueryRow(db, stmt) externalTable, err := snowflake.ScanExternalTable(row) if err != nil { - return err + if err.Error() == snowflake.ErrNoRowInRS { + fmt.Println("Good !!") + d.SetId("") + return nil + } else { + return err + } } err = d.Set("name", externalTable.ExternalTableName.String) diff --git a/pkg/resources/procedure.go b/pkg/resources/procedure.go index af6927d74b..ea487a8ab7 100644 --- a/pkg/resources/procedure.go +++ b/pkg/resources/procedure.go @@ -73,13 +73,13 @@ var procedureSchema = map[string]*schema.Schema{ DiffSuppressFunc: DiffSuppressStatement, }, "language": { - Type: schema.TypeString, - Optional: true, - Default: "SQL", + Type: schema.TypeString, + Optional: true, + Default: "SQL", // Suppress the diff shown if the values are equal when both compared in lower case. DiffSuppressFunc: DiffTypes, - ValidateFunc: validation.StringInSlice(procedureLanguages, true), - Description: "Specifies the language of the stored procedure code.", + ValidateFunc: validation.StringInSlice(procedureLanguages, true), + Description: "Specifies the language of the stored procedure code.", }, "execute_as": { Type: schema.TypeString, @@ -278,7 +278,7 @@ func ReadProcedure(d *schema.ResourceData, meta interface{}) error { if err = d.Set("language", desc.Value.String); err != nil { return err } - + default: log.Printf("[WARN] unexpected procedure property %v returned from Snowflake", desc.Property.String) } diff --git a/pkg/resources/user.go b/pkg/resources/user.go index cbc090c171..a6d268176f 100644 --- a/pkg/resources/user.go +++ b/pkg/resources/user.go @@ -3,6 +3,7 @@ package resources import ( "database/sql" "log" + "regexp" "strings" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/snowflake" @@ -132,6 +133,11 @@ 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, @@ -160,9 +166,10 @@ func ReadUser(d *schema.ResourceData, meta interface{}) error { // requires the "MANAGE GRANTS" global privilege stmt := snowflake.User(id).Describe() rows, err := snowflake.Query(db, stmt) - if err == sql.ErrNoRows { + + if err != nil && isUserNotExistOrNotAuthorized(err.Error()) { // If not found, mark resource to be removed from statefile during apply or refresh - log.Printf("[DEBUG] user (%s) not found", d.Id()) + log.Printf("[DEBUG] user (%s) not found or we are not authorized.Err:\n%s", d.Id(), err.Error()) d.SetId("") return nil } diff --git a/pkg/resources/user_test.go b/pkg/resources/user_test.go index a5c5e323ed..2636af44ae 100644 --- a/pkg/resources/user_test.go +++ b/pkg/resources/user_test.go @@ -5,6 +5,8 @@ import ( "fmt" "testing" + "github.com/pkg/errors" + sqlmock "github.com/DATA-DOG/go-sqlmock" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/resources" @@ -110,7 +112,7 @@ func TestUserRead(t *testing.T) { // Test when resource is not found, checking if state will be empty r.NotEmpty(d.State()) q := snowflake.User(d.Id()).Describe() - mock.ExpectQuery(q).WillReturnError(sql.ErrNoRows) + mock.ExpectQuery(q).WillReturnError(errors.New(fmt.Sprintf("SQL compilation error:User '%s' does not exist or not authorized.", name))) err2 := resources.ReadUser(d, db) r.Empty(d.State()) r.Nil(err2) diff --git a/pkg/snowflake/errors.go b/pkg/snowflake/errors.go new file mode 100644 index 0000000000..5147876bab --- /dev/null +++ b/pkg/snowflake/errors.go @@ -0,0 +1,6 @@ +package snowflake + +// Generic Errors +var ( + ErrNoRowInRS = "sql: no rows in result set" +)