From 0053db1853795d7547a64c8f8e34dcc2e0a9a02b Mon Sep 17 00:00:00 2001 From: Lukas Budisky Date: Wed, 20 Apr 2022 09:42:07 +0200 Subject: [PATCH] Before alter group make sure user still exists When there is no dependency between user and group or user is in multiple groups and was removed before then terraform will fail. After this commit we fix problem and during alter table we check if user still exists in redshift. --- redshift/resource_redshift_group.go | 37 +++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/redshift/resource_redshift_group.go b/redshift/resource_redshift_group.go index fc9caca..d09e945 100644 --- a/redshift/resource_redshift_group.go +++ b/redshift/resource_redshift_group.go @@ -213,6 +213,26 @@ func setGroupName(tx *sql.Tx, d *schema.ResourceData) error { return nil } +func checkIfUserExists(tx *sql.Tx, name interface{}) (bool, error) { + + username, ok := name.(string) + if !ok { + return false, fmt.Errorf("cannot convert username to string") + } + + var result int + err := tx.QueryRow("SELECT 1 from pg_user_info WHERE usename=$1", username).Scan(&result) + + switch err { + case sql.ErrNoRows: + return false, nil + case nil: + return false, fmt.Errorf("error reading info about user: %s", err) + } + + return true, nil +} + func setUsersNames(tx *sql.Tx, db *DBConnection, d *schema.ResourceData) error { if !d.HasChange(groupUsersAttr) { return nil @@ -226,13 +246,22 @@ func setUsersNames(tx *sql.Tx, db *DBConnection, d *schema.ResourceData) error { if removedUsers.Len() > 0 { removedUsersNamesSafe := []string{} for _, name := range removedUsers.List() { - removedUsersNamesSafe = append(removedUsersNamesSafe, pq.QuoteIdentifier(name.(string))) + userExists, err := checkIfUserExists(tx, name) + if err != nil { + return err + } + + if userExists { + removedUsersNamesSafe = append(removedUsersNamesSafe, pq.QuoteIdentifier(name.(string))) + } } - sql := fmt.Sprintf("ALTER GROUP %s DROP USER %s", pq.QuoteIdentifier(groupName), strings.Join(removedUsersNamesSafe, ", ")) + if len(removedUsersNamesSafe) > 0 { + sql := fmt.Sprintf("ALTER GROUP %s DROP USER %s", pq.QuoteIdentifier(groupName), strings.Join(removedUsersNamesSafe, ", ")) - if _, err := tx.Exec(sql); err != nil { - return err + if _, err := tx.Exec(sql); err != nil { + return err + } } }