From 694bc7626a609290cedd04275965cd026dd7aaea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Gut?= Date: Tue, 15 Nov 2022 11:14:57 +0100 Subject: [PATCH] Fix - preventing from non-idempotent reapplying grants for entities with ascii chars 33-126 in their names (#93) * Fix - preventing from non-idempotent reapplying grants for entities with ascii chars 33-126 in their names --- .../resource_redshift_default_privileges.go | 36 +- ...source_redshift_default_privileges_test.go | 342 +++++---- redshift/resource_redshift_grant.go | 56 +- redshift/resource_redshift_grant_test.go | 721 ++++++++++-------- redshift/resource_redshift_group_test.go | 132 ++-- 5 files changed, 686 insertions(+), 601 deletions(-) diff --git a/redshift/resource_redshift_default_privileges.go b/redshift/resource_redshift_default_privileges.go index fd94d62..af19f24 100644 --- a/redshift/resource_redshift_default_privileges.go +++ b/redshift/resource_redshift_default_privileges.go @@ -220,18 +220,18 @@ func readGroupTableDefaultPrivileges(tx *sql.Tx, d *schema.ResourceData, entityI if entityIsUser { query = ` SELECT - decode(charindex('r',split_part(split_part(regexp_replace(array_to_string(defaclacl, '|'), 'group '||u.usename), u.usename||'=', 2) ,'/',1)),0,0,1) as select, - decode(charindex('w',split_part(split_part(regexp_replace(array_to_string(defaclacl, '|'), 'group '||u.usename), u.usename||'=', 2) ,'/',1)),0,0,1) as update, - decode(charindex('a',split_part(split_part(regexp_replace(array_to_string(defaclacl, '|'), 'group '||u.usename), u.usename||'=', 2) ,'/',1)),0,0,1) as insert, - decode(charindex('d',split_part(split_part(regexp_replace(array_to_string(defaclacl, '|'), 'group '||u.usename), u.usename||'=', 2) ,'/',1)),0,0,1) as delete, - decode(charindex('D',split_part(split_part(regexp_replace(array_to_string(defaclacl, '|'), 'group '||u.usename), u.usename||'=', 2) ,'/',1)),0,0,1) as drop, - decode(charindex('x',split_part(split_part(regexp_replace(array_to_string(defaclacl, '|'), 'group '||u.usename), u.usename||'=', 2) ,'/',1)),0,0,1) as references, - decode(charindex('R',split_part(split_part(regexp_replace(array_to_string(defaclacl, '|'), 'group '||u.usename), u.usename||'=', 2) ,'/',1)),0,0,1) as rule, - decode(charindex('t',split_part(split_part(regexp_replace(array_to_string(defaclacl, '|'), 'group '||u.usename), u.usename||'=', 2) ,'/',1)),0,0,1) as trigger + decode(charindex('r',split_part(split_part(regexp_replace(replace(array_to_string(defaclacl, '|'), '"', ''), 'group '||u.usename), u.usename||'=', 2) ,'/',1)),0,0,1) as select, + decode(charindex('w',split_part(split_part(regexp_replace(replace(array_to_string(defaclacl, '|'), '"', ''), 'group '||u.usename), u.usename||'=', 2) ,'/',1)),0,0,1) as update, + decode(charindex('a',split_part(split_part(regexp_replace(replace(array_to_string(defaclacl, '|'), '"', ''), 'group '||u.usename), u.usename||'=', 2) ,'/',1)),0,0,1) as insert, + decode(charindex('d',split_part(split_part(regexp_replace(replace(array_to_string(defaclacl, '|'), '"', ''), 'group '||u.usename), u.usename||'=', 2) ,'/',1)),0,0,1) as delete, + decode(charindex('D',split_part(split_part(regexp_replace(replace(array_to_string(defaclacl, '|'), '"', ''), 'group '||u.usename), u.usename||'=', 2) ,'/',1)),0,0,1) as drop, + decode(charindex('x',split_part(split_part(regexp_replace(replace(array_to_string(defaclacl, '|'), '"', ''), 'group '||u.usename), u.usename||'=', 2) ,'/',1)),0,0,1) as references, + decode(charindex('R',split_part(split_part(regexp_replace(replace(array_to_string(defaclacl, '|'), '"', ''), 'group '||u.usename), u.usename||'=', 2) ,'/',1)),0,0,1) as rule, + decode(charindex('t',split_part(split_part(regexp_replace(replace(array_to_string(defaclacl, '|'), '"', ''), 'group '||u.usename), u.usename||'=', 2) ,'/',1)),0,0,1) as trigger FROM pg_user u, pg_default_acl acl WHERE acl.defaclnamespace = $1 - AND regexp_replace(array_to_string(acl.defaclacl, '|'), 'group '||u.usename) LIKE '%' || u.usename || '=%' + AND regexp_replace(replace(array_to_string(acl.defaclacl, '|'), '"', ''), 'group '||u.usename) LIKE '%' || u.usename || '=%' AND u.usesysid = $2 AND acl.defaclobjtype = $3 AND acl.defacluser = $4 @@ -239,18 +239,18 @@ func readGroupTableDefaultPrivileges(tx *sql.Tx, d *schema.ResourceData, entityI } else { query = ` SELECT - decode(charindex('r',split_part(split_part(array_to_string(defaclacl, '|'),'group ' || gr.groname,2 ) ,'/',1)),0,0,1) as select, - decode(charindex('w',split_part(split_part(array_to_string(defaclacl, '|'),'group ' || gr.groname,2 ) ,'/',1)),0,0,1) as update, - decode(charindex('a',split_part(split_part(array_to_string(defaclacl, '|'),'group ' || gr.groname,2 ) ,'/',1)),0,0,1) as insert, - decode(charindex('d',split_part(split_part(array_to_string(defaclacl, '|'),'group ' || gr.groname,2 ) ,'/',1)),0,0,1) as delete, - decode(charindex('D',split_part(split_part(array_to_string(defaclacl, '|'),'group ' || gr.groname,2 ) ,'/',1)),0,0,1) as drop, - decode(charindex('x',split_part(split_part(array_to_string(defaclacl, '|'),'group ' || gr.groname,2 ) ,'/',1)),0,0,1) as references, - decode(charindex('R',split_part(split_part(array_to_string(defaclacl, '|'),'group ' || gr.groname,2 ) ,'/',1)),0,0,1) as rule, - decode(charindex('t',split_part(split_part(array_to_string(defaclacl, '|'),'group ' || gr.groname,2 ) ,'/',1)),0,0,1) as trigger + decode(charindex('r',split_part(split_part(replace(array_to_string(defaclacl, '|'), '"', ''),'group ' || gr.groname,2 ) ,'/',1)),0,0,1) as select, + decode(charindex('w',split_part(split_part(replace(array_to_string(defaclacl, '|'), '"', ''),'group ' || gr.groname,2 ) ,'/',1)),0,0,1) as update, + decode(charindex('a',split_part(split_part(replace(array_to_string(defaclacl, '|'), '"', ''),'group ' || gr.groname,2 ) ,'/',1)),0,0,1) as insert, + decode(charindex('d',split_part(split_part(replace(array_to_string(defaclacl, '|'), '"', ''),'group ' || gr.groname,2 ) ,'/',1)),0,0,1) as delete, + decode(charindex('D',split_part(split_part(replace(array_to_string(defaclacl, '|'), '"', ''),'group ' || gr.groname,2 ) ,'/',1)),0,0,1) as drop, + decode(charindex('x',split_part(split_part(replace(array_to_string(defaclacl, '|'), '"', ''),'group ' || gr.groname,2 ) ,'/',1)),0,0,1) as references, + decode(charindex('R',split_part(split_part(replace(array_to_string(defaclacl, '|'), '"', ''),'group ' || gr.groname,2 ) ,'/',1)),0,0,1) as rule, + decode(charindex('t',split_part(split_part(replace(array_to_string(defaclacl, '|'), '"', ''),'group ' || gr.groname,2 ) ,'/',1)),0,0,1) as trigger FROM pg_group gr, pg_default_acl acl WHERE acl.defaclnamespace = $1 - AND array_to_string(acl.defaclacl, '|') LIKE '%' || 'group ' || gr.groname || '=%' + AND replace(array_to_string(acl.defaclacl, '|'), '"', '') LIKE '%' || 'group ' || gr.groname || '=%' AND gr.grosysid = $2 AND acl.defaclobjtype = $3 AND acl.defacluser = $4 diff --git a/redshift/resource_redshift_default_privileges_test.go b/redshift/resource_redshift_default_privileges_test.go index 2dd47ad..81bb47f 100644 --- a/redshift/resource_redshift_default_privileges_test.go +++ b/redshift/resource_redshift_default_privileges_test.go @@ -13,176 +13,194 @@ import ( ) func TestAccRedshiftDefaultPrivileges_Basic(t *testing.T) { - groupName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group"), "-", "_") - userName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user"), "-", "_") - config := fmt.Sprintf(` -resource "redshift_group" "group" { - name = %[1]q -} - -resource "redshift_user" "user" { - name = %[2]q - password = "TestPassword123" -} - -resource "redshift_default_privileges" "group" { - group = redshift_group.group.name - owner = "root" - object_type = "table" - privileges = ["select", "update", "insert", "delete", "drop", "references", "rule", "trigger"] -} - -resource "redshift_default_privileges" "user" { - user = redshift_user.user.name - owner = "root" - object_type = "table" - privileges = ["select", "update", "insert", "delete", "drop", "references", "rule", "trigger"] -} -`, groupName, userName) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDefaultPrivilegesDestory(defaultPrivilegesAllSchemasID, 100, "r", groupName), - Steps: []resource.TestStep{ - { - Config: config, - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("redshift_default_privileges.group", "id", fmt.Sprintf("gn:%s_noschema_on:root_ot:table", groupName)), - resource.TestCheckResourceAttr("redshift_default_privileges.group", "group", groupName), - resource.TestCheckResourceAttr("redshift_default_privileges.group", "object_type", "table"), - resource.TestCheckResourceAttr("redshift_default_privileges.group", "privileges.#", "8"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "select"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "update"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "insert"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "delete"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "drop"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "references"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "rule"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "trigger"), + groupNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group@tf_acc_domain.tld"), "-", "_"), + } + userNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user@tf_acc_domain.tld"), "-", "_"), + } - resource.TestCheckResourceAttr("redshift_default_privileges.user", "id", fmt.Sprintf("un:%s_noschema_on:root_ot:table", userName)), - resource.TestCheckResourceAttr("redshift_default_privileges.user", "user", userName), - resource.TestCheckResourceAttr("redshift_default_privileges.user", "object_type", "table"), - resource.TestCheckResourceAttr("redshift_default_privileges.user", "privileges.#", "8"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "select"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "update"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "insert"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "delete"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "drop"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "references"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "rule"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "trigger"), - ), + for i, groupName := range groupNames { + userName := userNames[i] + config := fmt.Sprintf(` + resource "redshift_group" "group" { + name = %[1]q + } + + resource "redshift_user" "user" { + name = %[2]q + password = "TestPassword123" + } + + resource "redshift_default_privileges" "group" { + group = redshift_group.group.name + owner = "root" + object_type = "table" + privileges = ["select", "update", "insert", "delete", "drop", "references", "rule", "trigger"] + } + + resource "redshift_default_privileges" "user" { + user = redshift_user.user.name + owner = "root" + object_type = "table" + privileges = ["select", "update", "insert", "delete", "drop", "references", "rule", "trigger"] + } + `, groupName, userName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckDefaultPrivilegesDestory(defaultPrivilegesAllSchemasID, 100, "r", groupName), + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("redshift_default_privileges.group", "id", fmt.Sprintf("gn:%s_noschema_on:root_ot:table", groupName)), + resource.TestCheckResourceAttr("redshift_default_privileges.group", "group", groupName), + resource.TestCheckResourceAttr("redshift_default_privileges.group", "object_type", "table"), + resource.TestCheckResourceAttr("redshift_default_privileges.group", "privileges.#", "8"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "select"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "update"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "insert"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "delete"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "drop"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "references"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "rule"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "trigger"), + + resource.TestCheckResourceAttr("redshift_default_privileges.user", "id", fmt.Sprintf("un:%s_noschema_on:root_ot:table", userName)), + resource.TestCheckResourceAttr("redshift_default_privileges.user", "user", userName), + resource.TestCheckResourceAttr("redshift_default_privileges.user", "object_type", "table"), + resource.TestCheckResourceAttr("redshift_default_privileges.user", "privileges.#", "8"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "select"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "update"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "insert"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "delete"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "drop"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "references"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "rule"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "trigger"), + ), + }, }, - }, - }) + }) + } } func TestAccRedshiftDefaultPrivileges_UpdateToRevoke(t *testing.T) { - groupName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group"), "-", "_") - userName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user"), "-", "_") - configInitial := fmt.Sprintf(` -resource "redshift_group" "group" { - name = %[1]q -} - -resource "redshift_user" "user" { - name = %[2]q - password = "TestPassword123" -} - -resource "redshift_default_privileges" "group" { - group = redshift_group.group.name - owner = "root" - object_type = "table" - privileges = ["select", "update", "insert", "delete", "drop", "references", "rule", "trigger"] -} - -resource "redshift_default_privileges" "user" { - user = redshift_user.user.name - owner = "root" - object_type = "table" - privileges = ["select", "update", "insert", "delete", "drop", "references", "rule", "trigger"] -} -`, groupName, userName) - - configUpdated := fmt.Sprintf(` -resource "redshift_group" "group" { - name = %[1]q -} - -resource "redshift_user" "user" { - name = %[2]q - password = "TestPassword123" -} - -resource "redshift_default_privileges" "group" { - group = redshift_group.group.name - owner = "root" - object_type = "table" - privileges = [] -} - -resource "redshift_default_privileges" "user" { - user = redshift_user.user.name - owner = "root" - object_type = "table" - privileges = [] -} -`, groupName, userName) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckDefaultPrivilegesDestory(defaultPrivilegesAllSchemasID, 100, "r", groupName), - Steps: []resource.TestStep{ - { - Config: configInitial, - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("redshift_default_privileges.group", "id", fmt.Sprintf("gn:%s_noschema_on:root_ot:table", groupName)), - resource.TestCheckResourceAttr("redshift_default_privileges.group", "group", groupName), - resource.TestCheckResourceAttr("redshift_default_privileges.group", "object_type", "table"), - resource.TestCheckResourceAttr("redshift_default_privileges.group", "privileges.#", "8"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "select"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "update"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "insert"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "delete"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "drop"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "references"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "rule"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "trigger"), + groupNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group@tf_acc_domain.tld"), "-", "_"), + } + userNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user@tf_acc_domain.tld"), "-", "_"), + } - resource.TestCheckResourceAttr("redshift_default_privileges.user", "id", fmt.Sprintf("un:%s_noschema_on:root_ot:table", userName)), - resource.TestCheckResourceAttr("redshift_default_privileges.user", "user", userName), - resource.TestCheckResourceAttr("redshift_default_privileges.user", "object_type", "table"), - resource.TestCheckResourceAttr("redshift_default_privileges.user", "privileges.#", "8"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "select"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "update"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "insert"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "delete"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "drop"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "references"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "rule"), - resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "trigger"), - ), - }, - { - Config: configUpdated, - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("redshift_default_privileges.group", "id", fmt.Sprintf("gn:%s_noschema_on:root_ot:table", groupName)), - resource.TestCheckResourceAttr("redshift_default_privileges.group", "group", groupName), - resource.TestCheckResourceAttr("redshift_default_privileges.group", "object_type", "table"), - resource.TestCheckResourceAttr("redshift_default_privileges.group", "privileges.#", "0"), + for i, groupName := range groupNames { + userName := userNames[i] + configInitial := fmt.Sprintf(` + resource "redshift_group" "group" { + name = %[1]q + } + + resource "redshift_user" "user" { + name = %[2]q + password = "TestPassword123" + } + + resource "redshift_default_privileges" "group" { + group = redshift_group.group.name + owner = "root" + object_type = "table" + privileges = ["select", "update", "insert", "delete", "drop", "references", "rule", "trigger"] + } + + resource "redshift_default_privileges" "user" { + user = redshift_user.user.name + owner = "root" + object_type = "table" + privileges = ["select", "update", "insert", "delete", "drop", "references", "rule", "trigger"] + } + `, groupName, userName) - resource.TestCheckResourceAttr("redshift_default_privileges.user", "id", fmt.Sprintf("un:%s_noschema_on:root_ot:table", userName)), - resource.TestCheckResourceAttr("redshift_default_privileges.user", "user", userName), - resource.TestCheckResourceAttr("redshift_default_privileges.user", "object_type", "table"), - resource.TestCheckResourceAttr("redshift_default_privileges.user", "privileges.#", "0"), - ), + configUpdated := fmt.Sprintf(` + resource "redshift_group" "group" { + name = %[1]q + } + + resource "redshift_user" "user" { + name = %[2]q + password = "TestPassword123" + } + + resource "redshift_default_privileges" "group" { + group = redshift_group.group.name + owner = "root" + object_type = "table" + privileges = [] + } + + resource "redshift_default_privileges" "user" { + user = redshift_user.user.name + owner = "root" + object_type = "table" + privileges = [] + } + `, groupName, userName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckDefaultPrivilegesDestory(defaultPrivilegesAllSchemasID, 100, "r", groupName), + Steps: []resource.TestStep{ + { + Config: configInitial, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("redshift_default_privileges.group", "id", fmt.Sprintf("gn:%s_noschema_on:root_ot:table", groupName)), + resource.TestCheckResourceAttr("redshift_default_privileges.group", "group", groupName), + resource.TestCheckResourceAttr("redshift_default_privileges.group", "object_type", "table"), + resource.TestCheckResourceAttr("redshift_default_privileges.group", "privileges.#", "8"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "select"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "update"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "insert"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "delete"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "drop"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "references"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "rule"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.group", "privileges.*", "trigger"), + + resource.TestCheckResourceAttr("redshift_default_privileges.user", "id", fmt.Sprintf("un:%s_noschema_on:root_ot:table", userName)), + resource.TestCheckResourceAttr("redshift_default_privileges.user", "user", userName), + resource.TestCheckResourceAttr("redshift_default_privileges.user", "object_type", "table"), + resource.TestCheckResourceAttr("redshift_default_privileges.user", "privileges.#", "8"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "select"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "update"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "insert"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "delete"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "drop"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "references"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "rule"), + resource.TestCheckTypeSetElemAttr("redshift_default_privileges.user", "privileges.*", "trigger"), + ), + }, + { + Config: configUpdated, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("redshift_default_privileges.group", "id", fmt.Sprintf("gn:%s_noschema_on:root_ot:table", groupName)), + resource.TestCheckResourceAttr("redshift_default_privileges.group", "group", groupName), + resource.TestCheckResourceAttr("redshift_default_privileges.group", "object_type", "table"), + resource.TestCheckResourceAttr("redshift_default_privileges.group", "privileges.#", "0"), + + resource.TestCheckResourceAttr("redshift_default_privileges.user", "id", fmt.Sprintf("un:%s_noschema_on:root_ot:table", userName)), + resource.TestCheckResourceAttr("redshift_default_privileges.user", "user", userName), + resource.TestCheckResourceAttr("redshift_default_privileges.user", "object_type", "table"), + resource.TestCheckResourceAttr("redshift_default_privileges.user", "privileges.#", "0"), + ), + }, }, - }, - }) + }) + } } func TestAccRedshiftDefaultPrivileges_BothUserGroupError(t *testing.T) { diff --git a/redshift/resource_redshift_grant.go b/redshift/resource_redshift_grant.go index 0ede967..2810c6f 100644 --- a/redshift/resource_redshift_grant.go +++ b/redshift/resource_redshift_grant.go @@ -210,8 +210,8 @@ func readDatabaseGrants(db *DBConnection, d *schema.ResourceData) error { entityName = d.Get(grantUserAttr).(string) query = ` SELECT - decode(charindex('C',split_part(split_part(regexp_replace(array_to_string(db.datacl, '|'),'group '||u.usename,'__avoidGroupPrivs__'), u.usename||'=', 2) ,'/',1)), 0,0,1) as create, - decode(charindex('T',split_part(split_part(regexp_replace(array_to_string(db.datacl, '|'),'group '||u.usename,'__avoidGroupPrivs__'), u.usename||'=', 2) ,'/',1)), 0,0,1) as temporary + decode(charindex('C',split_part(split_part(regexp_replace(replace(array_to_string(db.datacl, '|'), '"', ''),'group '||u.usename,'__avoidGroupPrivs__'), u.usename||'=', 2) ,'/',1)), 0,0,1) as create, + decode(charindex('T',split_part(split_part(regexp_replace(replace(array_to_string(db.datacl, '|'), '"', ''),'group '||u.usename,'__avoidGroupPrivs__'), u.usename||'=', 2) ,'/',1)), 0,0,1) as temporary FROM pg_database db, pg_user u WHERE db.datname=$1 @@ -221,8 +221,8 @@ func readDatabaseGrants(db *DBConnection, d *schema.ResourceData) error { entityName = d.Get(grantGroupAttr).(string) query = ` SELECT - decode(charindex('C',split_part(split_part(array_to_string(db.datacl, '|'),'group ' || gr.groname,2 ) ,'/',1)), 0,0,1) as create, - decode(charindex('T',split_part(split_part(array_to_string(db.datacl, '|'),'group ' || gr.groname,2 ) ,'/',1)), 0,0,1) as temporary + decode(charindex('C',split_part(split_part(replace(array_to_string(db.datacl, '|'), '"', ''),'group ' || gr.groname,2 ) ,'/',1)), 0,0,1) as create, + decode(charindex('T',split_part(split_part(replace(array_to_string(db.datacl, '|'), '"', ''),'group ' || gr.groname,2 ) ,'/',1)), 0,0,1) as temporary FROM pg_database db, pg_group gr WHERE db.datname=$1 @@ -256,8 +256,8 @@ func readSchemaGrants(db *DBConnection, d *schema.ResourceData) error { entityName = d.Get(grantUserAttr).(string) query = ` SELECT - decode(charindex('C',split_part(split_part(regexp_replace(array_to_string(ns.nspacl, '|'),'group '||u.usename,'__avoidGroupPrivs__'), u.usename||'=', 2) ,'/',1)), 0,0,1) as create, - decode(charindex('U',split_part(split_part(regexp_replace(array_to_string(ns.nspacl, '|'),'group '||u.usename,'__avoidGroupPrivs__'), u.usename||'=', 2) ,'/',1)), 0,0,1) as usage + decode(charindex('C',split_part(split_part(regexp_replace(replace(array_to_string(ns.nspacl, '|'), '"', ''),'group '||u.usename,'__avoidGroupPrivs__'), u.usename||'=', 2) ,'/',1)), 0,0,1) as create, + decode(charindex('U',split_part(split_part(regexp_replace(replace(array_to_string(ns.nspacl, '|'), '"', ''),'group '||u.usename,'__avoidGroupPrivs__'), u.usename||'=', 2) ,'/',1)), 0,0,1) as usage FROM pg_namespace ns, pg_user u WHERE ns.nspname=$1 @@ -267,8 +267,8 @@ func readSchemaGrants(db *DBConnection, d *schema.ResourceData) error { entityName = d.Get(grantGroupAttr).(string) query = ` SELECT - decode(charindex('C',split_part(split_part(array_to_string(ns.nspacl, '|'),'group ' || gr.groname || '=',2 ) ,'/',1)), 0,0,1) as create, - decode(charindex('U',split_part(split_part(array_to_string(ns.nspacl, '|'),'group ' || gr.groname || '=',2 ) ,'/',1)), 0,0,1) as usage + decode(charindex('C',split_part(split_part(replace(array_to_string(ns.nspacl, '|'), '"', ''),'group ' || gr.groname || '=',2 ) ,'/',1)), 0,0,1) as create, + decode(charindex('U',split_part(split_part(replace(array_to_string(ns.nspacl, '|'), '"', ''),'group ' || gr.groname || '=',2 ) ,'/',1)), 0,0,1) as usage FROM pg_namespace ns, pg_group gr WHERE ns.nspname=$1 @@ -300,14 +300,14 @@ func readTableGrants(db *DBConnection, d *schema.ResourceData) error { query = ` SELECT relname, - decode(charindex('r',split_part(split_part(regexp_replace(array_to_string(relacl, '|'),'group '||u.usename), u.usename||'=', 2) ,'/',1)),null,0,0,0,1) as select, - decode(charindex('w',split_part(split_part(regexp_replace(array_to_string(relacl, '|'),'group '||u.usename), u.usename||'=', 2) ,'/',1)),null,0,0,0,1) as update, - decode(charindex('a',split_part(split_part(regexp_replace(array_to_string(relacl, '|'),'group '||u.usename), u.usename||'=', 2) ,'/',1)),null,0,0,0,1) as insert, - decode(charindex('d',split_part(split_part(regexp_replace(array_to_string(relacl, '|'),'group '||u.usename), u.usename||'=', 2) ,'/',1)),null,0,0,0,1) as delete, - decode(charindex('D',split_part(split_part(regexp_replace(array_to_string(relacl, '|'),'group '||u.usename), u.usename||'=', 2) ,'/',1)),null,0,0,0,1) as drop, - decode(charindex('x',split_part(split_part(regexp_replace(array_to_string(relacl, '|'),'group '||u.usename), u.usename||'=', 2) ,'/',1)),null,0,0,0,1) as references, - decode(charindex('R',split_part(split_part(regexp_replace(array_to_string(relacl, '|'),'group '||u.usename), u.usename||'=', 2) ,'/',1)),null,0,0,0,1) as rule, - decode(charindex('t',split_part(split_part(regexp_replace(array_to_string(relacl, '|'),'group '||u.usename), u.usename||'=', 2) ,'/',1)),null,0,0,0,1) as trigger + decode(charindex('r',split_part(split_part(regexp_replace(replace(array_to_string(relacl, '|'), '"', ''),'group '||u.usename), u.usename||'=', 2) ,'/',1)),null,0,0,0,1) as select, + decode(charindex('w',split_part(split_part(regexp_replace(replace(array_to_string(relacl, '|'), '"', ''),'group '||u.usename), u.usename||'=', 2) ,'/',1)),null,0,0,0,1) as update, + decode(charindex('a',split_part(split_part(regexp_replace(replace(array_to_string(relacl, '|'), '"', ''),'group '||u.usename), u.usename||'=', 2) ,'/',1)),null,0,0,0,1) as insert, + decode(charindex('d',split_part(split_part(regexp_replace(replace(array_to_string(relacl, '|'), '"', ''),'group '||u.usename), u.usename||'=', 2) ,'/',1)),null,0,0,0,1) as delete, + decode(charindex('D',split_part(split_part(regexp_replace(replace(array_to_string(relacl, '|'), '"', ''),'group '||u.usename), u.usename||'=', 2) ,'/',1)),null,0,0,0,1) as drop, + decode(charindex('x',split_part(split_part(regexp_replace(replace(array_to_string(relacl, '|'), '"', ''),'group '||u.usename), u.usename||'=', 2) ,'/',1)),null,0,0,0,1) as references, + decode(charindex('R',split_part(split_part(regexp_replace(replace(array_to_string(relacl, '|'), '"', ''),'group '||u.usename), u.usename||'=', 2) ,'/',1)),null,0,0,0,1) as rule, + decode(charindex('t',split_part(split_part(regexp_replace(replace(array_to_string(relacl, '|'), '"', ''),'group '||u.usename), u.usename||'=', 2) ,'/',1)),null,0,0,0,1) as trigger FROM pg_user u, pg_class cl JOIN pg_namespace nsp ON nsp.oid = cl.relnamespace WHERE @@ -320,14 +320,14 @@ func readTableGrants(db *DBConnection, d *schema.ResourceData) error { query = ` SELECT relname, - decode(charindex('r',split_part(split_part(array_to_string(relacl, '|'),'group ' || gr.groname || '=',2 ) ,'/',1)), null,0, 0,0, 1) as select, - decode(charindex('w',split_part(split_part(array_to_string(relacl, '|'),'group ' || gr.groname || '=',2 ) ,'/',1)), null,0, 0,0, 1) as update, - decode(charindex('a',split_part(split_part(array_to_string(relacl, '|'),'group ' || gr.groname || '=',2 ) ,'/',1)), null,0, 0,0, 1) as insert, - decode(charindex('d',split_part(split_part(array_to_string(relacl, '|'),'group ' || gr.groname || '=',2 ) ,'/',1)), null,0, 0,0, 1) as delete, - decode(charindex('D',split_part(split_part(array_to_string(relacl, '|'),'group ' || gr.groname || '=',2 ) ,'/',1)), null,0, 0,0, 1) as drop, - decode(charindex('x',split_part(split_part(array_to_string(relacl, '|'),'group ' || gr.groname || '=',2 ) ,'/',1)), null,0, 0,0, 1) as references, - decode(charindex('R',split_part(split_part(array_to_string(relacl, '|'),'group ' || gr.groname || '=',2 ) ,'/',1)), null,0, 0,0, 1) as rule, - decode(charindex('t',split_part(split_part(array_to_string(relacl, '|'),'group ' || gr.groname || '=',2 ) ,'/',1)), null,0, 0,0, 1) as trigger + decode(charindex('r',split_part(split_part(replace(array_to_string(relacl, '|'), '"', ''),'group ' || gr.groname || '=',2 ) ,'/',1)), null,0, 0,0, 1) as select, + decode(charindex('w',split_part(split_part(replace(array_to_string(relacl, '|'), '"', ''),'group ' || gr.groname || '=',2 ) ,'/',1)), null,0, 0,0, 1) as update, + decode(charindex('a',split_part(split_part(replace(array_to_string(relacl, '|'), '"', ''),'group ' || gr.groname || '=',2 ) ,'/',1)), null,0, 0,0, 1) as insert, + decode(charindex('d',split_part(split_part(replace(array_to_string(relacl, '|'), '"', ''),'group ' || gr.groname || '=',2 ) ,'/',1)), null,0, 0,0, 1) as delete, + decode(charindex('D',split_part(split_part(replace(array_to_string(relacl, '|'), '"', ''),'group ' || gr.groname || '=',2 ) ,'/',1)), null,0, 0,0, 1) as drop, + decode(charindex('x',split_part(split_part(replace(array_to_string(relacl, '|'), '"', ''),'group ' || gr.groname || '=',2 ) ,'/',1)), null,0, 0,0, 1) as references, + decode(charindex('R',split_part(split_part(replace(array_to_string(relacl, '|'), '"', ''),'group ' || gr.groname || '=',2 ) ,'/',1)), null,0, 0,0, 1) as rule, + decode(charindex('t',split_part(split_part(replace(array_to_string(relacl, '|'), '"', ''),'group ' || gr.groname || '=',2 ) ,'/',1)), null,0, 0,0, 1) as trigger FROM pg_group gr, pg_class cl JOIN pg_namespace nsp ON nsp.oid = cl.relnamespace WHERE @@ -404,7 +404,7 @@ func readCallableGrants(db *DBConnection, d *schema.ResourceData) error { query = ` SELECT proname, - decode(nvl(charindex('X',split_part(split_part(regexp_replace(array_to_string(pr.proacl, '|'),'group '||u.usename,'__avoidGroupPrivs__'), u.usename||'=', 2) ,'/',1)), 0), 0,0,1) as execute + decode(nvl(charindex('X',split_part(split_part(regexp_replace(replace(array_to_string(pr.proacl, '|'), '"', ''),'group '||u.usename,'__avoidGroupPrivs__'), u.usename||'=', 2) ,'/',1)), 0), 0,0,1) as execute FROM pg_proc_info pr JOIN pg_namespace nsp ON nsp.oid = pr.pronamespace, pg_user u @@ -418,7 +418,7 @@ func readCallableGrants(db *DBConnection, d *schema.ResourceData) error { query = ` SELECT proname, - decode(nvl(charindex('X',split_part(split_part(array_to_string(pr.proacl, '|'),'group ' || gr.groname,2 ) ,'/',1)), 0), 0,0,1) as execute + decode(nvl(charindex('X',split_part(split_part(replace(array_to_string(pr.proacl, '|'), '"', ''),'group ' || gr.groname,2 ) ,'/',1)), 0), 0,0,1) as execute FROM pg_proc_info pr JOIN pg_namespace nsp ON nsp.oid = pr.pronamespace, pg_group gr @@ -480,7 +480,7 @@ func readLanguageGrants(db *DBConnection, d *schema.ResourceData) error { query = ` SELECT lanname, - decode(nvl(charindex('U',split_part(split_part(regexp_replace(array_to_string(lg.lanacl, '|'),'group '||u.usename,'__avoidGroupPrivs__'), u.usename||'=', 2) ,'/',1)), 0), 0,0,1) as usage + decode(nvl(charindex('U',split_part(split_part(regexp_replace(replace(array_to_string(lg.lanacl, '|'), '"', ''),'group '||u.usename,'__avoidGroupPrivs__'), u.usename||'=', 2) ,'/',1)), 0), 0,0,1) as usage FROM pg_language lg, pg_user u WHERE u.usename=$1 @@ -490,7 +490,7 @@ func readLanguageGrants(db *DBConnection, d *schema.ResourceData) error { query = ` SELECT lanname, - decode(nvl(charindex('U',split_part(split_part(array_to_string(lg.lanacl, '|'),'group ' || gr.groname,2 ) ,'/',1)), 0), 0,0,1) as usage + decode(nvl(charindex('U',split_part(split_part(replace(array_to_string(lg.lanacl, '|'), '"', ''),'group ' || gr.groname,2 ) ,'/',1)), 0), 0,0,1) as usage FROM pg_language lg, pg_group gr WHERE gr.groname=$1 diff --git a/redshift/resource_redshift_grant_test.go b/redshift/resource_redshift_grant_test.go index b96723f..4450fc3 100644 --- a/redshift/resource_redshift_grant_test.go +++ b/redshift/resource_redshift_grant_test.go @@ -12,383 +12,430 @@ import ( ) func TestAccRedshiftGrant_BasicDatabase(t *testing.T) { - groupName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group_basic"), "-", "_") - userName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user_basic"), "-", "_") - - config := fmt.Sprintf(` -resource "redshift_group" "group" { - name = %[1]q -} - -resource "redshift_user" "user" { - name = %[2]q - password = "TestPassword123" -} - -resource "redshift_grant" "grant" { - group = redshift_group.group.name - object_type = "database" - privileges = ["create", "temporary"] -} - -resource "redshift_grant" "grant_user" { - user = redshift_user.user.name - object_type = "database" - privileges = ["temporary"] -} -`, groupName, userName) + groupNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group@tf_acc_domain.tld"), "-", "_"), + } + userNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user@tf_acc_domain.tld"), "-", "_"), + } - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: func(s *terraform.State) error { return nil }, - Steps: []resource.TestStep{ - { - Config: config, - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("redshift_grant.grant", "id", fmt.Sprintf("gn:%s_ot:database", groupName)), - resource.TestCheckResourceAttr("redshift_grant.grant", "group", groupName), - resource.TestCheckResourceAttr("redshift_grant.grant", "object_type", "database"), - resource.TestCheckResourceAttr("redshift_grant.grant", "privileges.#", "2"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "create"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "temporary"), - - resource.TestCheckResourceAttr("redshift_grant.grant_user", "id", fmt.Sprintf("un:%s_ot:database", userName)), - resource.TestCheckResourceAttr("redshift_grant.grant_user", "user", userName), - resource.TestCheckResourceAttr("redshift_grant.grant_user", "object_type", "database"), - resource.TestCheckResourceAttr("redshift_grant.grant_user", "privileges.#", "1"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "temporary"), - ), + for i, groupName := range groupNames { + userName := userNames[i] + config := fmt.Sprintf(` + resource "redshift_group" "group" { + name = %[1]q + } + + resource "redshift_user" "user" { + name = %[2]q + password = "TestPassword123" + } + + resource "redshift_grant" "grant" { + group = redshift_group.group.name + object_type = "database" + privileges = ["create", "temporary"] + } + + resource "redshift_grant" "grant_user" { + user = redshift_user.user.name + object_type = "database" + privileges = ["temporary"] + } + `, groupName, userName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: func(s *terraform.State) error { return nil }, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("redshift_grant.grant", "id", fmt.Sprintf("gn:%s_ot:database", groupName)), + resource.TestCheckResourceAttr("redshift_grant.grant", "group", groupName), + resource.TestCheckResourceAttr("redshift_grant.grant", "object_type", "database"), + resource.TestCheckResourceAttr("redshift_grant.grant", "privileges.#", "2"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "create"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "temporary"), + + resource.TestCheckResourceAttr("redshift_grant.grant_user", "id", fmt.Sprintf("un:%s_ot:database", userName)), + resource.TestCheckResourceAttr("redshift_grant.grant_user", "user", userName), + resource.TestCheckResourceAttr("redshift_grant.grant_user", "object_type", "database"), + resource.TestCheckResourceAttr("redshift_grant.grant_user", "privileges.#", "1"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "temporary"), + ), + }, }, - }, - }) + }) + } } func TestAccRedshiftGrant_BasicSchema(t *testing.T) { - userName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user_basic"), "-", "_") - groupName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group_basic"), "-", "_") + groupNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group@tf_acc_domain.tld"), "-", "_"), + } + userNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user@tf_acc_domain.tld"), "-", "_"), + } schemaName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_schema_basic"), "-", "_") - config := fmt.Sprintf(` -resource "redshift_user" "user" { - name = %[1]q -} - -resource "redshift_group" "group" { - name = %[2]q -} - -resource "redshift_schema" "schema" { - name = %[3]q - - owner = redshift_user.user.name -} - -resource "redshift_grant" "grant" { - group = redshift_group.group.name - schema = redshift_schema.schema.name - - object_type = "schema" - privileges = ["create", "usage"] -} - -resource "redshift_grant" "grant_user" { - user = redshift_user.user.name - schema = redshift_schema.schema.name - - object_type = "schema" - privileges = ["create", "usage"] -} -`, userName, groupName, schemaName) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: func(s *terraform.State) error { return nil }, - Steps: []resource.TestStep{ - { - Config: config, - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("redshift_grant.grant", "id", fmt.Sprintf("gn:%s_ot:schema_%s", groupName, schemaName)), - resource.TestCheckResourceAttr("redshift_grant.grant", "group", groupName), - resource.TestCheckResourceAttr("redshift_grant.grant", "object_type", "schema"), - resource.TestCheckResourceAttr("redshift_grant.grant", "privileges.#", "2"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "create"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "usage"), - - resource.TestCheckResourceAttr("redshift_grant.grant_user", "id", fmt.Sprintf("un:%s_ot:schema_%s", userName, schemaName)), - resource.TestCheckResourceAttr("redshift_grant.grant_user", "user", userName), - resource.TestCheckResourceAttr("redshift_grant.grant_user", "object_type", "schema"), - resource.TestCheckResourceAttr("redshift_grant.grant_user", "privileges.#", "2"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "create"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "usage"), - ), + for i, groupName := range groupNames { + userName := userNames[i] + config := fmt.Sprintf(` + resource "redshift_user" "user" { + name = %[1]q + } + + resource "redshift_group" "group" { + name = %[2]q + } + + resource "redshift_schema" "schema" { + name = %[3]q + + owner = redshift_user.user.name + } + + resource "redshift_grant" "grant" { + group = redshift_group.group.name + schema = redshift_schema.schema.name + + object_type = "schema" + privileges = ["create", "usage"] + } + + resource "redshift_grant" "grant_user" { + user = redshift_user.user.name + schema = redshift_schema.schema.name + + object_type = "schema" + privileges = ["create", "usage"] + } + `, userName, groupName, schemaName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: func(s *terraform.State) error { return nil }, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("redshift_grant.grant", "id", fmt.Sprintf("gn:%s_ot:schema_%s", groupName, schemaName)), + resource.TestCheckResourceAttr("redshift_grant.grant", "group", groupName), + resource.TestCheckResourceAttr("redshift_grant.grant", "object_type", "schema"), + resource.TestCheckResourceAttr("redshift_grant.grant", "privileges.#", "2"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "create"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "usage"), + + resource.TestCheckResourceAttr("redshift_grant.grant_user", "id", fmt.Sprintf("un:%s_ot:schema_%s", userName, schemaName)), + resource.TestCheckResourceAttr("redshift_grant.grant_user", "user", userName), + resource.TestCheckResourceAttr("redshift_grant.grant_user", "object_type", "schema"), + resource.TestCheckResourceAttr("redshift_grant.grant_user", "privileges.#", "2"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "create"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "usage"), + ), + }, }, - }, - }) + }) + } } func TestAccRedshiftGrant_BasicTable(t *testing.T) { - groupName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group_basic"), "-", "_") - userName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user_basic"), "-", "_") - config := fmt.Sprintf(` -resource "redshift_group" "group" { - name = %[1]q -} - -resource "redshift_user" "user" { - name = %[2]q - password = "TestPassword123" -} - -resource "redshift_grant" "grant" { - group = redshift_group.group.name - schema = "pg_catalog" - - object_type = "table" - objects = ["pg_user_info"] - privileges = ["select", "update", "insert", "delete", "drop", "references", "rule", "trigger"] -} - -resource "redshift_grant" "grant_user" { - user = redshift_user.user.name - schema = "pg_catalog" - - object_type = "table" - objects = ["pg_user_info"] - privileges = ["select", "update", "insert", "delete", "drop", "references", "rule", "trigger"] -} -`, groupName, userName) + groupNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group@tf_acc_domain.tld"), "-", "_"), + } + userNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user@tf_acc_domain.tld"), "-", "_"), + } - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: func(s *terraform.State) error { return nil }, - Steps: []resource.TestStep{ - { - Config: config, - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("redshift_grant.grant", "id", fmt.Sprintf("gn:%s_ot:table_pg_catalog_pg_user_info", groupName)), - resource.TestCheckResourceAttr("redshift_grant.grant", "group", groupName), - resource.TestCheckResourceAttr("redshift_grant.grant", "schema", "pg_catalog"), - resource.TestCheckResourceAttr("redshift_grant.grant", "object_type", "table"), - resource.TestCheckResourceAttr("redshift_grant.grant", "objects.#", "1"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "objects.*", "pg_user_info"), - resource.TestCheckResourceAttr("redshift_grant.grant", "privileges.#", "8"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "select"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "update"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "insert"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "delete"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "drop"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "references"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "rule"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "trigger"), - - resource.TestCheckResourceAttr("redshift_grant.grant_user", "id", fmt.Sprintf("un:%s_ot:table_pg_catalog_pg_user_info", userName)), - resource.TestCheckResourceAttr("redshift_grant.grant_user", "user", userName), - resource.TestCheckResourceAttr("redshift_grant.grant_user", "schema", "pg_catalog"), - resource.TestCheckResourceAttr("redshift_grant.grant_user", "object_type", "table"), - resource.TestCheckResourceAttr("redshift_grant.grant_user", "objects.#", "1"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "objects.*", "pg_user_info"), - resource.TestCheckResourceAttr("redshift_grant.grant_user", "privileges.#", "8"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "select"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "update"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "insert"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "delete"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "drop"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "references"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "rule"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "trigger"), - ), + for i, groupName := range groupNames { + userName := userNames[i] + config := fmt.Sprintf(` + resource "redshift_group" "group" { + name = %[1]q + } + + resource "redshift_user" "user" { + name = %[2]q + password = "TestPassword123" + } + + resource "redshift_grant" "grant" { + group = redshift_group.group.name + schema = "pg_catalog" + + object_type = "table" + objects = ["pg_user_info"] + privileges = ["select", "update", "insert", "delete", "drop", "references", "rule", "trigger"] + } + + resource "redshift_grant" "grant_user" { + user = redshift_user.user.name + schema = "pg_catalog" + + object_type = "table" + objects = ["pg_user_info"] + privileges = ["select", "update", "insert", "delete", "drop", "references", "rule", "trigger"] + } + `, groupName, userName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: func(s *terraform.State) error { return nil }, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("redshift_grant.grant", "id", fmt.Sprintf("gn:%s_ot:table_pg_catalog_pg_user_info", groupName)), + resource.TestCheckResourceAttr("redshift_grant.grant", "group", groupName), + resource.TestCheckResourceAttr("redshift_grant.grant", "schema", "pg_catalog"), + resource.TestCheckResourceAttr("redshift_grant.grant", "object_type", "table"), + resource.TestCheckResourceAttr("redshift_grant.grant", "objects.#", "1"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "objects.*", "pg_user_info"), + resource.TestCheckResourceAttr("redshift_grant.grant", "privileges.#", "8"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "select"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "update"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "insert"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "delete"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "drop"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "references"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "rule"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "trigger"), + + resource.TestCheckResourceAttr("redshift_grant.grant_user", "id", fmt.Sprintf("un:%s_ot:table_pg_catalog_pg_user_info", userName)), + resource.TestCheckResourceAttr("redshift_grant.grant_user", "user", userName), + resource.TestCheckResourceAttr("redshift_grant.grant_user", "schema", "pg_catalog"), + resource.TestCheckResourceAttr("redshift_grant.grant_user", "object_type", "table"), + resource.TestCheckResourceAttr("redshift_grant.grant_user", "objects.#", "1"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "objects.*", "pg_user_info"), + resource.TestCheckResourceAttr("redshift_grant.grant_user", "privileges.#", "8"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "select"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "update"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "insert"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "delete"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "drop"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "references"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "rule"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "trigger"), + ), + }, }, - }, - }) + }) + } } func TestAccRedshiftGrant_BasicCallables(t *testing.T) { - userName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user_basic"), "-", "_") - groupName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group_basic"), "-", "_") + groupNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group@tf_acc_domain.tld"), "-", "_"), + } + userNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user@tf_acc_domain.tld"), "-", "_"), + } schema := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_schema_basic"), "-", "_") - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: func(s *terraform.State) error { return nil }, - Steps: []resource.TestStep{ - { - Config: testAccRedshiftGrant_basicCallables_configUserGroup(userName, groupName, schema), - }, - { - PreConfig: func() { - dbClient := testAccProvider.Meta().(*Client) - conn, err := dbClient.Connect() - defer dbClient.Close() - if err != nil { - t.Fatalf("couldn't start redshift connection: %s", err) - } - err = testAccRedshiftGrant_basicCallables_createSchemaAndCallables(t, conn, schema) - if err != nil { - t.Fatalf("couldn't setup database: %s", err) - } + for i, groupName := range groupNames { + userName := userNames[i] + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: func(s *terraform.State) error { return nil }, + Steps: []resource.TestStep{ + { + Config: testAccRedshiftGrant_basicCallables_configUserGroup(userName, groupName, schema), }, - Config: testAccRedshiftGrant_basicCallables_configUserGroupWithGrants(userName, groupName, schema), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("redshift_grant.grant_fun", "id", fmt.Sprintf("gn:%s_ot:function_%s_test_call(float,float)", groupName, schema)), - resource.TestCheckResourceAttr("redshift_grant.grant_fun", "group", groupName), - resource.TestCheckResourceAttr("redshift_grant.grant_fun", "object_type", "function"), - resource.TestCheckResourceAttr("redshift_grant.grant_fun", "privileges.#", "1"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_fun", "privileges.*", "execute"), - resource.TestCheckResourceAttr("redshift_grant.grant_proc", "id", fmt.Sprintf("gn:%s_ot:procedure_%s_test_call()", groupName, schema)), - resource.TestCheckResourceAttr("redshift_grant.grant_proc", "group", groupName), - resource.TestCheckResourceAttr("redshift_grant.grant_proc", "object_type", "procedure"), - resource.TestCheckResourceAttr("redshift_grant.grant_proc", "privileges.#", "1"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_proc", "privileges.*", "execute"), - - resource.TestCheckResourceAttr("redshift_grant.grant_user_fun", "id", fmt.Sprintf("un:%s_ot:function_%s_test_call(int,int)_test_call(float,float)", userName, schema)), - resource.TestCheckResourceAttr("redshift_grant.grant_user_fun", "user", userName), - resource.TestCheckResourceAttr("redshift_grant.grant_user_fun", "object_type", "function"), - resource.TestCheckResourceAttr("redshift_grant.grant_user_fun", "privileges.#", "1"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user_fun", "privileges.*", "execute"), - resource.TestCheckResourceAttr("redshift_grant.grant_user_proc", "id", fmt.Sprintf("un:%s_ot:procedure_%s_test_call()", userName, schema)), - resource.TestCheckResourceAttr("redshift_grant.grant_user_proc", "user", userName), - resource.TestCheckResourceAttr("redshift_grant.grant_user_proc", "object_type", "procedure"), - resource.TestCheckResourceAttr("redshift_grant.grant_user_proc", "privileges.#", "1"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user_proc", "privileges.*", "execute"), - ), - }, - { - Config: testAccRedshiftGrant_basicCallables_configUserGroupWithGrants(userName, groupName, schema), - Destroy: true, - }, - // Creating additional dummy step as TestStep does not have PostConfig - // property, so clean up cannot be performed in the previous one. - { - PreConfig: func() { - dbClient := testAccProvider.Meta().(*Client) - conn, err := dbClient.Connect() - defer dbClient.Close() - if err != nil { - t.Errorf("couldn't cleanup resources: %s", err) - } - err = testAccRedshiftGrant_basicCallables_dropResources(t, conn, schema) - if err != nil { - t.Errorf("couldn't cleanup resources: %s", err) - } + { + PreConfig: func() { + dbClient := testAccProvider.Meta().(*Client) + conn, err := dbClient.Connect() + defer dbClient.Close() + if err != nil { + t.Fatalf("couldn't start redshift connection: %s", err) + } + err = testAccRedshiftGrant_basicCallables_createSchemaAndCallables(t, conn, schema) + if err != nil { + t.Fatalf("couldn't setup database: %s", err) + } + }, + Config: testAccRedshiftGrant_basicCallables_configUserGroupWithGrants(userName, groupName, schema), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("redshift_grant.grant_fun", "id", fmt.Sprintf("gn:%s_ot:function_%s_test_call(float,float)", groupName, schema)), + resource.TestCheckResourceAttr("redshift_grant.grant_fun", "group", groupName), + resource.TestCheckResourceAttr("redshift_grant.grant_fun", "object_type", "function"), + resource.TestCheckResourceAttr("redshift_grant.grant_fun", "privileges.#", "1"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_fun", "privileges.*", "execute"), + resource.TestCheckResourceAttr("redshift_grant.grant_proc", "id", fmt.Sprintf("gn:%s_ot:procedure_%s_test_call()", groupName, schema)), + resource.TestCheckResourceAttr("redshift_grant.grant_proc", "group", groupName), + resource.TestCheckResourceAttr("redshift_grant.grant_proc", "object_type", "procedure"), + resource.TestCheckResourceAttr("redshift_grant.grant_proc", "privileges.#", "1"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_proc", "privileges.*", "execute"), + + resource.TestCheckResourceAttr("redshift_grant.grant_user_fun", "id", fmt.Sprintf("un:%s_ot:function_%s_test_call(int,int)_test_call(float,float)", userName, schema)), + resource.TestCheckResourceAttr("redshift_grant.grant_user_fun", "user", userName), + resource.TestCheckResourceAttr("redshift_grant.grant_user_fun", "object_type", "function"), + resource.TestCheckResourceAttr("redshift_grant.grant_user_fun", "privileges.#", "1"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user_fun", "privileges.*", "execute"), + resource.TestCheckResourceAttr("redshift_grant.grant_user_proc", "id", fmt.Sprintf("un:%s_ot:procedure_%s_test_call()", userName, schema)), + resource.TestCheckResourceAttr("redshift_grant.grant_user_proc", "user", userName), + resource.TestCheckResourceAttr("redshift_grant.grant_user_proc", "object_type", "procedure"), + resource.TestCheckResourceAttr("redshift_grant.grant_user_proc", "privileges.#", "1"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user_proc", "privileges.*", "execute"), + ), + }, + { + Config: testAccRedshiftGrant_basicCallables_configUserGroupWithGrants(userName, groupName, schema), + Destroy: true, + }, + // Creating additional dummy step as TestStep does not have PostConfig + // property, so clean up cannot be performed in the previous one. + { + PreConfig: func() { + dbClient := testAccProvider.Meta().(*Client) + conn, err := dbClient.Connect() + defer dbClient.Close() + if err != nil { + t.Errorf("couldn't cleanup resources: %s", err) + } + err = testAccRedshiftGrant_basicCallables_dropResources(t, conn, schema) + if err != nil { + t.Errorf("couldn't cleanup resources: %s", err) + } + }, + Config: testAccRedshiftGrant_basicCallables_configUserGroupWithGrants(userName, groupName, schema), + PlanOnly: true, + Destroy: true, }, - Config: testAccRedshiftGrant_basicCallables_configUserGroupWithGrants(userName, groupName, schema), - PlanOnly: true, - Destroy: true, }, - }, - }) + }) + } } func TestAccRedshiftGrant_BasicLanguage(t *testing.T) { - userName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user_basic"), "-", "_") - groupName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group_basic"), "-", "_") + groupNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group@tf_acc_domain.tld"), "-", "_"), + } + userNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user@tf_acc_domain.tld"), "-", "_"), + } addedLanguage := "plpythonu" secondLanguage := "plpgsql" - config := fmt.Sprintf(` -resource "redshift_user" "user" { - name = %[1]q -} - -resource "redshift_group" "group" { - name = %[2]q -} - -resource "redshift_grant" "grant" { - group = redshift_group.group.name - objects = [%[3]q, %[4]q] - - object_type = "language" - privileges = ["usage"] -} - -resource "redshift_grant" "grant_user" { - user = redshift_user.user.name - objects = [%[3]q, %[4]q] - - object_type = "language" - privileges = ["usage"] -} -`, userName, groupName, addedLanguage, secondLanguage) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: func(s *terraform.State) error { return nil }, - Steps: []resource.TestStep{ - { - Config: config, - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("redshift_grant.grant", "id", fmt.Sprintf("gn:%s_ot:language_%s_%s", groupName, addedLanguage, secondLanguage)), - resource.TestCheckResourceAttr("redshift_grant.grant", "group", groupName), - resource.TestCheckResourceAttr("redshift_grant.grant", "object_type", "language"), - resource.TestCheckResourceAttr("redshift_grant.grant", "privileges.#", "1"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "usage"), - - resource.TestCheckResourceAttr("redshift_grant.grant_user", "id", fmt.Sprintf("un:%s_ot:language_%s_%s", userName, addedLanguage, secondLanguage)), - resource.TestCheckResourceAttr("redshift_grant.grant_user", "user", userName), - resource.TestCheckResourceAttr("redshift_grant.grant_user", "object_type", "language"), - resource.TestCheckResourceAttr("redshift_grant.grant_user", "privileges.#", "1"), - resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "usage"), - ), + for i, groupName := range groupNames { + userName := userNames[i] + config := fmt.Sprintf(` + resource "redshift_user" "user" { + name = %[1]q + } + + resource "redshift_group" "group" { + name = %[2]q + } + + resource "redshift_grant" "grant" { + group = redshift_group.group.name + objects = [%[3]q, %[4]q] + + object_type = "language" + privileges = ["usage"] + } + + resource "redshift_grant" "grant_user" { + user = redshift_user.user.name + objects = [%[3]q, %[4]q] + + object_type = "language" + privileges = ["usage"] + } + `, userName, groupName, addedLanguage, secondLanguage) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: func(s *terraform.State) error { return nil }, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("redshift_grant.grant", "id", fmt.Sprintf("gn:%s_ot:language_%s_%s", groupName, addedLanguage, secondLanguage)), + resource.TestCheckResourceAttr("redshift_grant.grant", "group", groupName), + resource.TestCheckResourceAttr("redshift_grant.grant", "object_type", "language"), + resource.TestCheckResourceAttr("redshift_grant.grant", "privileges.#", "1"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant", "privileges.*", "usage"), + + resource.TestCheckResourceAttr("redshift_grant.grant_user", "id", fmt.Sprintf("un:%s_ot:language_%s_%s", userName, addedLanguage, secondLanguage)), + resource.TestCheckResourceAttr("redshift_grant.grant_user", "user", userName), + resource.TestCheckResourceAttr("redshift_grant.grant_user", "object_type", "language"), + resource.TestCheckResourceAttr("redshift_grant.grant_user", "privileges.#", "1"), + resource.TestCheckTypeSetElemAttr("redshift_grant.grant_user", "privileges.*", "usage"), + ), + }, }, - }, - }) + }) + } } func TestAccRedshiftGrant_Regression_GH_Issue_24(t *testing.T) { - userName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user_grant"), "-", "_") + userNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user@tf_acc_domain.tld"), "-", "_"), + } schemaName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_schema_grant"), "-", "_") dbName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_db_grant"), "-", "_") - config := fmt.Sprintf(` -resource "redshift_user" "user" { - name = %[1]q -} -# Create a group named the same as user -resource "redshift_group" "group" { - name = %[1]q -} + for _, userName := range userNames { + config := fmt.Sprintf(` + resource "redshift_user" "user" { + name = %[1]q + } -# Create a schema and set user as owner -resource "redshift_schema" "schema" { - name = %[2]q + # Create a group named the same as user + resource "redshift_group" "group" { + name = %[1]q + } - owner = redshift_user.user.name -} + # Create a schema and set user as owner + resource "redshift_schema" "schema" { + name = %[2]q -# The schema owner user will have all (create, usage) privileges on the schema -# Set only 'create' privilege to a group with the same name as user. In previous versions this would trigger a permanent diff in plan. -resource "redshift_grant" "schema" { - group = redshift_group.group.name - schema = redshift_schema.schema.name + owner = redshift_user.user.name + } - object_type = "schema" - privileges = ["create"] -} -`, userName, schemaName, dbName) + # The schema owner user will have all (create, usage) privileges on the schema + # Set only 'create' privilege to a group with the same name as user. In previous versions this would trigger a permanent diff in plan. + resource "redshift_grant" "schema" { + group = redshift_group.group.name + schema = redshift_schema.schema.name - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: func(s *terraform.State) error { return nil }, - Steps: []resource.TestStep{ - { - Config: config, - Check: resource.ComposeTestCheckFunc(), - }, - // The 'ExpectNonEmptyPlan: false' option will fail the test if second run on the same config will show any changes - { - Config: config, - Check: resource.ComposeTestCheckFunc(), - ExpectNonEmptyPlan: false, + object_type = "schema" + privileges = ["create"] + } + `, userName, schemaName, dbName) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: func(s *terraform.State) error { return nil }, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc(), + }, + // The 'ExpectNonEmptyPlan: false' option will fail the test if second run on the same config will show any changes + { + Config: config, + Check: resource.ComposeTestCheckFunc(), + ExpectNonEmptyPlan: false, + }, }, - }, - }) + }) + } } func TestAccRedshiftGrant_Regression_Issue_43(t *testing.T) { diff --git a/redshift/resource_redshift_group_test.go b/redshift/resource_redshift_group_test.go index cdb5f2e..dbbe41b 100644 --- a/redshift/resource_redshift_group_test.go +++ b/redshift/resource_redshift_group_test.go @@ -40,67 +40,87 @@ func TestAccRedshiftGroup_Basic(t *testing.T) { } func TestAccRedshiftGroup_Update(t *testing.T) { - groupName := strings.ReplaceAll(acctest.RandomWithPrefix("TF_acc_group"), "-", "_") + groupNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("TF_acc_group"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group@tf_acc_domain.tld"), "-", "_"), + } + userNames := []string{ + strings.ReplaceAll(acctest.RandomWithPrefix("TF_Acc_Group_User"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group_user"), "-", "_"), + strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_user@tf_acc_domain.tld"), "-", "_"), + } groupNameUpdated := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group_updated"), "-", "_") - userName1 := strings.ReplaceAll(acctest.RandomWithPrefix("TF_Acc_Group_User"), "-", "_") - userName2 := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_group_user"), "-", "_") - configCreate := fmt.Sprintf(` -resource "redshift_group" "update_group" { - name = %[1]q -} -`, groupName) - configUpdate := fmt.Sprintf(` -resource "redshift_user" "group_update_user1" { - name = %[1]q -} + for _, groupName := range groupNames { + userName1 := userNames[0] + userName2 := userNames[1] + userName3 := userNames[2] -resource "redshift_user" "group_update_user2" { - name = %[2]q -} + configCreate := fmt.Sprintf(` + resource "redshift_group" "update_group" { + name = %[1]q + } + `, groupName) -resource "redshift_group" "update_group" { - name = %[3]q - users = [ - redshift_user.group_update_user1.name, - redshift_user.group_update_user2.name, - ] -} -`, userName1, userName2, groupNameUpdated) - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckRedshiftGroupDestroy, - Steps: []resource.TestStep{ - { - Config: configCreate, - Check: resource.ComposeTestCheckFunc( - testAccCheckRedshiftGroupExists(groupName), - resource.TestCheckResourceAttr("redshift_group.update_group", "name", strings.ToLower(groupName)), - resource.TestCheckResourceAttr("redshift_group.update_group", "users.#", "0"), - ), - }, - { - Config: configUpdate, - Check: resource.ComposeTestCheckFunc( - testAccCheckRedshiftGroupExists(groupNameUpdated), - resource.TestCheckResourceAttr("redshift_group.update_group", "name", strings.ToLower(groupNameUpdated)), - resource.TestCheckResourceAttr("redshift_group.update_group", "users.#", "2"), - resource.TestCheckTypeSetElemAttr("redshift_group.update_group", "users.*", userName1), - resource.TestCheckTypeSetElemAttr("redshift_group.update_group", "users.*", userName2), - ), - }, - // apply the first one again to check if all parameters roll back properly - { - Config: configCreate, - Check: resource.ComposeTestCheckFunc( - testAccCheckRedshiftGroupExists(groupName), - resource.TestCheckResourceAttr("redshift_group.update_group", "name", strings.ToLower(groupName)), - resource.TestCheckResourceAttr("redshift_group.update_group", "users.#", "0"), - ), + configUpdate := fmt.Sprintf(` + resource "redshift_user" "group_update_user1" { + name = %[1]q + } + + resource "redshift_user" "group_update_user2" { + name = %[2]q + } + + resource "redshift_user" "group_update_user3" { + name = %[3]q + } + + resource "redshift_group" "update_group" { + name = %[4]q + users = [ + redshift_user.group_update_user1.name, + redshift_user.group_update_user2.name, + redshift_user.group_update_user3.name, + ] + } + `, userName1, userName2, userName3, groupNameUpdated) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckRedshiftGroupDestroy, + Steps: []resource.TestStep{ + { + Config: configCreate, + Check: resource.ComposeTestCheckFunc( + testAccCheckRedshiftGroupExists(groupName), + resource.TestCheckResourceAttr("redshift_group.update_group", "name", strings.ToLower(groupName)), + resource.TestCheckResourceAttr("redshift_group.update_group", "users.#", "0"), + ), + }, + { + Config: configUpdate, + Check: resource.ComposeTestCheckFunc( + testAccCheckRedshiftGroupExists(groupNameUpdated), + resource.TestCheckResourceAttr("redshift_group.update_group", "name", strings.ToLower(groupNameUpdated)), + resource.TestCheckResourceAttr("redshift_group.update_group", "users.#", "3"), + resource.TestCheckTypeSetElemAttr("redshift_group.update_group", "users.*", userName1), + resource.TestCheckTypeSetElemAttr("redshift_group.update_group", "users.*", userName2), + resource.TestCheckTypeSetElemAttr("redshift_group.update_group", "users.*", userName3), + ), + }, + // apply the first one again to check if all parameters roll back properly + { + Config: configCreate, + Check: resource.ComposeTestCheckFunc( + testAccCheckRedshiftGroupExists(groupName), + resource.TestCheckResourceAttr("redshift_group.update_group", "name", strings.ToLower(groupName)), + resource.TestCheckResourceAttr("redshift_group.update_group", "users.#", "0"), + ), + }, }, - }, - }) + }) + } } func TestAccRedshiftGroup_RemoveExistingUser(t *testing.T) {