diff --git a/postgresql/resource_postgresql_default_privileges.go b/postgresql/resource_postgresql_default_privileges.go index 45418682..d2a578d1 100644 --- a/postgresql/resource_postgresql_default_privileges.go +++ b/postgresql/resource_postgresql_default_privileges.go @@ -57,12 +57,11 @@ func resourcePostgreSQLDefaultPrivileges() *schema.Resource { }, false), Description: "The PostgreSQL object type to set the default privileges on (one of: table, sequence, function, type)", }, - "privileges": &schema.Schema{ + "privileges": { Type: schema.TypeSet, Required: true, Elem: &schema.Schema{Type: schema.TypeString}, Set: schema.HashString, - MinItems: 1, Description: "The list of privileges to apply as default privileges", }, "with_grant_option": { @@ -183,6 +182,7 @@ func readRoleDefaultPrivileges(txn *sql.Tx, d *schema.ResourceData) error { owner := d.Get("owner").(string) pgSchema := d.Get("schema").(string) objectType := d.Get("object_type").(string) + privilegesInput := d.Get("privileges").(*schema.Set).List() if err := pgLockRole(txn, owner); err != nil { return err @@ -226,11 +226,13 @@ func readRoleDefaultPrivileges(txn *sql.Tx, d *schema.ResourceData) error { return fmt.Errorf("could not read default privileges: %w", err) } - // We consider no privileges as "not exists" + // We consider no privileges as "not exists" unless no privileges were provided as input if len(privileges) == 0 { log.Printf("[DEBUG] no default privileges for role %s in schema %s", role, pgSchema) - d.SetId("") - return nil + if len(privilegesInput) != 0 { + d.SetId("") + return nil + } } privilegesSet := pgArrayToSet(privileges) @@ -249,6 +251,11 @@ func grantRoleDefaultPrivileges(txn *sql.Tx, d *schema.ResourceData) error { privileges = append(privileges, priv.(string)) } + if len(privileges) == 0 { + log.Printf("[DEBUG] no default privileges to grant for role %s, owner %s in database: %s,", d.Get("role").(string), d.Get("owner").(string), d.Get("database").(string)) + return nil + } + var inSchema string // If a schema is specified we need to build the part of the query string to action this diff --git a/postgresql/resource_postgresql_default_privileges_test.go b/postgresql/resource_postgresql_default_privileges_test.go index 59fc1ebb..9013ae64 100644 --- a/postgresql/resource_postgresql_default_privileges_test.go +++ b/postgresql/resource_postgresql_default_privileges_test.go @@ -48,6 +48,23 @@ resource "postgresql_default_privileges" "test_ro" { }, Providers: testAccProviders, Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(tfConfig, `[]`), + Check: resource.ComposeTestCheckFunc( + func(*terraform.State) error { + tables := []string{"test_schema.test_table"} + // To test default privileges, we need to create a table + // after having apply the state. + dropFunc := createTestTables(t, dbSuffix, tables, "") + defer dropFunc() + + return testCheckTablesPrivileges(t, dbName, roleName, tables, []string{}) + }, + resource.TestCheckResourceAttr("postgresql_default_privileges.test_ro", "object_type", "table"), + resource.TestCheckResourceAttr("postgresql_default_privileges.test_ro", "with_grant_option", fmt.Sprintf("%t", withGrant)), + resource.TestCheckResourceAttr("postgresql_default_privileges.test_ro", "privileges.#", "0"), + ), + }, { Config: fmt.Sprintf(tfConfig, `["SELECT"]`), Check: resource.ComposeTestCheckFunc( @@ -83,6 +100,23 @@ resource "postgresql_default_privileges" "test_ro" { resource.TestCheckResourceAttr("postgresql_default_privileges.test_ro", "privileges.1759376126", "UPDATE"), ), }, + { + Config: fmt.Sprintf(tfConfig, `[]`), + Check: resource.ComposeTestCheckFunc( + func(*terraform.State) error { + tables := []string{"test_schema.test_table"} + // To test default privileges, we need to create a table + // after having apply the state. + dropFunc := createTestTables(t, dbSuffix, tables, "") + defer dropFunc() + + return testCheckTablesPrivileges(t, dbName, roleName, tables, []string{}) + }, + resource.TestCheckResourceAttr("postgresql_default_privileges.test_ro", "object_type", "table"), + resource.TestCheckResourceAttr("postgresql_default_privileges.test_ro", "with_grant_option", fmt.Sprintf("%t", withGrant)), + resource.TestCheckResourceAttr("postgresql_default_privileges.test_ro", "privileges.#", "0"), + ), + }, }, }) }) diff --git a/website/docs/r/postgresql_default_privileges.html.markdown b/website/docs/r/postgresql_default_privileges.html.markdown index c48ba064..d078ea3d 100644 --- a/website/docs/r/postgresql_default_privileges.html.markdown +++ b/website/docs/r/postgresql_default_privileges.html.markdown @@ -31,6 +31,21 @@ resource "postgresql_default_privileges" "read_only_tables" { * `role` - (Required) The name of the role to which grant default privileges on. * `database` - (Required) The database to grant default privileges for this role. * `owner` - (Required) Role for which apply default privileges (You can change default privileges only for objects that will be created by yourself or by roles that you are a member of). -* `schema` - (Required) The database schema to set default privileges for this role. +* `schema` - (Optional) The database schema to set default privileges for this role. * `object_type` - (Required) The PostgreSQL object type to set the default privileges on (one of: table, sequence, function, type). -* `privileges` - (Required) The list of privileges to apply as default privileges. +* `privileges` - (Required) The list of privileges to apply as default privileges. An empty list could be provided to revoke all default privileges for this role. + + +## Examples + +Revoke default privileges for functions for "public" role: + +```hcl +resource "postgresql_default_priviliges" "revoke_public" { + database = postgresql_database.example_db.name + role = "public" + owner = "object_owner" + object_type = "function" + privileges = [] +} +```