diff --git a/docs/data-sources/user.md b/docs/data-sources/user.md new file mode 100644 index 00000000..7081198d --- /dev/null +++ b/docs/data-sources/user.md @@ -0,0 +1,40 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "redshift_user Data Source - terraform-provider-redshift" +subcategory: "" +description: |- + This data source can be used to fetch information about a specific database user. Users are authenticated when they login to Amazon Redshift. They can own databases and database objects (for example, tables) and can grant privileges on those objects to users, groups, and schemas to control who has access to which object. Users with CREATE DATABASE rights can create databases and grant privileges to those databases. Superusers have database ownership privileges for all databases. +--- + +# redshift_user (Data Source) + +This data source can be used to fetch information about a specific database user. Users are authenticated when they login to Amazon Redshift. They can own databases and database objects (for example, tables) and can grant privileges on those objects to users, groups, and schemas to control who has access to which object. Users with CREATE DATABASE rights can create databases and grant privileges to those databases. Superusers have database ownership privileges for all databases. + +## Example Usage + +```terraform +data "redshift_user" "user" { + name = "UserName" +} +``` + + +## Schema + +### Required + +- **name** (String) The name of the user account. The user name can't be `PUBLIC`. + +### Optional + +- **id** (String) The ID of this resource. + +### Read-Only + +- **connection_limit** (Number) The maximum number of database connections the user is permitted to have open concurrently. The limit isn't enforced for superusers. +- **create_database** (Boolean) Indicates whether the user is allowed to create new databases. +- **superuser** (Boolean) Indicates whether the user is a superuser with all database privileges. +- **syslog_access** (String) A clause that specifies the level of access that the user has to the Amazon Redshift system tables and views. If `RESTRICTED` (default) is specified, the user can see only the rows generated by that user in user-visible system tables and views. If `UNRESTRICTED` is specified, the user can see all rows in user-visible system tables and views, including rows generated by another user. `UNRESTRICTED` doesn't give a regular user access to superuser-visible tables. Only superusers can see superuser-visible tables. +- **valid_until** (String) Date and time after which the user's password is no longer valid. By default the password has no time limit. + + diff --git a/examples/data-sources/redshift_user/data-source.tf b/examples/data-sources/redshift_user/data-source.tf new file mode 100644 index 00000000..554fd2c4 --- /dev/null +++ b/examples/data-sources/redshift_user/data-source.tf @@ -0,0 +1,3 @@ +data "redshift_user" "user" { + name = "UserName" +} diff --git a/redshift/data_source_redshift_user.go b/redshift/data_source_redshift_user.go new file mode 100644 index 00000000..4f3bf467 --- /dev/null +++ b/redshift/data_source_redshift_user.go @@ -0,0 +1,107 @@ +package redshift + +import ( + "fmt" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func dataSourceRedshiftUser() *schema.Resource { + return &schema.Resource{ + Description: ` +This data source can be used to fetch information about a specific database user. Users are authenticated when they login to Amazon Redshift. They can own databases and database objects (for example, tables) and can grant privileges on those objects to users, groups, and schemas to control who has access to which object. Users with CREATE DATABASE rights can create databases and grant privileges to those databases. Superusers have database ownership privileges for all databases. +`, + Read: RedshiftResourceFunc(dataSourceRedshiftUserRead), + Schema: map[string]*schema.Schema{ + userNameAttr: { + Type: schema.TypeString, + Required: true, + Description: "The name of the user account. The user name can't be `PUBLIC`.", + ValidateFunc: validation.StringNotInSlice([]string{ + "public", + }, true), + StateFunc: func(val interface{}) string { + return strings.ToLower(val.(string)) + }, + }, + userValidUntilAttr: { + Type: schema.TypeString, + Computed: true, + Description: "Date and time after which the user's password is no longer valid. By default the password has no time limit.", + }, + userCreateDBAttr: { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether the user is allowed to create new databases.", + }, + userConnLimitAttr: { + Type: schema.TypeInt, + Computed: true, + Description: "The maximum number of database connections the user is permitted to have open concurrently. The limit isn't enforced for superusers.", + }, + userSyslogAccessAttr: { + Type: schema.TypeString, + Computed: true, + Description: "A clause that specifies the level of access that the user has to the Amazon Redshift system tables and views. If `RESTRICTED` (default) is specified, the user can see only the rows generated by that user in user-visible system tables and views. If `UNRESTRICTED` is specified, the user can see all rows in user-visible system tables and views, including rows generated by another user. `UNRESTRICTED` doesn't give a regular user access to superuser-visible tables. Only superusers can see superuser-visible tables.", + }, + userSuperuserAttr: { + Type: schema.TypeBool, + Computed: true, + Description: `Indicates whether the user is a superuser with all database privileges.`, + }, + }, + } +} + +func dataSourceRedshiftUserRead(db *DBConnection, d *schema.ResourceData) error { + var useSysID, userValidUntil, userConnLimit, userSyslogAccess string + var userSuperuser, userCreateDB bool + + columns := []string{ + "usesysid", + "usecreatedb", + "usesuper", + "syslogaccess", + `COALESCE(useconnlimit::TEXT, 'UNLIMITED')`, + } + + values := []interface{}{ + &useSysID, + &userCreateDB, + &userSuperuser, + &userSyslogAccess, + &userConnLimit, + } + + userName := d.Get(userNameAttr).(string) + + userSQL := fmt.Sprintf("SELECT %s FROM svl_user_info WHERE usename = $1", strings.Join(columns, ",")) + err := db.QueryRow(userSQL, userName).Scan(values...) + if err != nil { + return err + } + + err = db.QueryRow("SELECT COALESCE(valuntil, 'infinity') FROM pg_user_info WHERE usesysid = $1", useSysID).Scan(&userValidUntil) + if err != nil { + return err + } + + userConnLimitNumber := -1 + if userConnLimit != "UNLIMITED" { + if userConnLimitNumber, err = strconv.Atoi(userConnLimit); err != nil { + return err + } + } + + d.SetId(useSysID) + d.Set(userCreateDBAttr, userCreateDB) + d.Set(userSuperuserAttr, userSuperuser) + d.Set(userSyslogAccessAttr, userSyslogAccess) + d.Set(userConnLimitAttr, userConnLimitNumber) + d.Set(userValidUntilAttr, userValidUntil) + + return nil +} diff --git a/redshift/data_source_redshift_user_test.go b/redshift/data_source_redshift_user_test.go new file mode 100644 index 00000000..7e7ae9fc --- /dev/null +++ b/redshift/data_source_redshift_user_test.go @@ -0,0 +1,45 @@ +package redshift + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccDataSourceRedshiftUser_Basic(t *testing.T) { + userName := strings.ReplaceAll(acctest.RandomWithPrefix("tf_acc_data_user_basic"), "-", "_") + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckRedshiftUserDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceRedshiftUserConfig_Basic(userName), + Check: resource.ComposeTestCheckFunc( + testAccCheckRedshiftUserExists(userName), + resource.TestCheckResourceAttr("data.redshift_user.simple", userNameAttr, userName), + resource.TestCheckResourceAttrSet("data.redshift_user.simple", userValidUntilAttr), + resource.TestCheckResourceAttrSet("data.redshift_user.simple", userCreateDBAttr), + resource.TestCheckResourceAttrSet("data.redshift_user.simple", userConnLimitAttr), + resource.TestCheckResourceAttrSet("data.redshift_user.simple", userSyslogAccessAttr), + resource.TestCheckResourceAttrSet("data.redshift_user.simple", userSuperuserAttr), + ), + }, + }, + }) +} + +func testAccDataSourceRedshiftUserConfig_Basic(userName string) string { + return fmt.Sprintf(` +resource "redshift_user" "simple" { + %[1]s = %[2]q +} + +data "redshift_user" "simple" { + %[1]s = redshift_user.simple.%[1]s +} +`, userNameAttr, userName) +} diff --git a/redshift/provider.go b/redshift/provider.go index 3798d82a..9062c292 100644 --- a/redshift/provider.go +++ b/redshift/provider.go @@ -122,6 +122,7 @@ func Provider() *schema.Provider { "redshift_privilege": redshiftPrivilege(), }, DataSourcesMap: map[string]*schema.Resource{ + "redshift_user": dataSourceRedshiftUser(), "redshift_group": dataSourceRedshiftGroup(), }, ConfigureFunc: providerConfigure,