Skip to content

Commit 8cf0072

Browse files
committed
Fix inconsistent plan
1 parent 23e6817 commit 8cf0072

File tree

1 file changed

+77
-40
lines changed

1 file changed

+77
-40
lines changed

postgresql/resource_postgresql_default_privileges.go

Lines changed: 77 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func resourcePostgreSQLDefaultPrivileges() *schema.Resource {
3535
},
3636
"owner": {
3737
Type: schema.TypeString,
38-
Required: true,
38+
Optional: true,
3939
ForceNew: true,
4040
Description: "Target role for which to alter default privileges.",
4141
},
@@ -100,6 +100,11 @@ func resourcePostgreSQLDefaultPrivilegesRead(db *DBConnection, d *schema.Resourc
100100
if err != nil {
101101
return err
102102
}
103+
log.Printf(
104+
"[DEBUG] Starting transaction for reading default privileges for role %s in database %s",
105+
d.Get("role").(string),
106+
d.Get("database").(string),
107+
)
103108
defer deferredRollback(txn)
104109

105110
return readRoleDefaultPrivileges(txn, d)
@@ -136,26 +141,33 @@ func resourcePostgreSQLDefaultPrivilegesCreate(db *DBConnection, d *schema.Resou
136141
}
137142
defer deferredRollback(txn)
138143

139-
if err := pgLockRole(txn, owner); err != nil {
140-
return err
141-
}
144+
// Only execute withRolesGranted if owner is non-empty
145+
if owner != "" {
146+
if err := pgLockRole(txn, owner); err != nil {
147+
return err
148+
}
142149

143-
// Needed in order to set the owner of the db if the connection user is not a superuser
144-
if err := withRolesGranted(txn, []string{owner}, func() error {
150+
if err := withRolesGranted(txn, []string{owner}, func() error {
151+
// Revoke and grant default privileges
152+
if err = revokeRoleDefaultPrivileges(txn, d); err != nil {
153+
return err
154+
}
145155

146-
// Revoke all privileges before granting otherwise reducing privileges will not work.
147-
// We just have to revoke them in the same transaction so role will not lose its privileges
148-
// between revoke and grant.
156+
if err = grantRoleDefaultPrivileges(txn, d); err != nil {
157+
return err
158+
}
159+
return nil
160+
}); err != nil {
161+
return err
162+
}
163+
} else {
149164
if err = revokeRoleDefaultPrivileges(txn, d); err != nil {
150165
return err
151166
}
152167

153168
if err = grantRoleDefaultPrivileges(txn, d); err != nil {
154169
return err
155170
}
156-
return nil
157-
}); err != nil {
158-
return err
159171
}
160172

161173
if err := txn.Commit(); err != nil {
@@ -168,6 +180,7 @@ func resourcePostgreSQLDefaultPrivilegesCreate(db *DBConnection, d *schema.Resou
168180
if err != nil {
169181
return err
170182
}
183+
171184
defer deferredRollback(txn)
172185

173186
return readRoleDefaultPrivileges(txn, d)
@@ -191,15 +204,16 @@ func resourcePostgreSQLDefaultPrivilegesDelete(db *DBConnection, d *schema.Resou
191204
}
192205
defer deferredRollback(txn)
193206

194-
if err := pgLockRole(txn, owner); err != nil {
195-
return err
196-
}
197-
198207
// Needed in order to set the owner of the db if the connection user is not a superuser
199-
if err := withRolesGranted(txn, []string{owner}, func() error {
200-
return revokeRoleDefaultPrivileges(txn, d)
201-
}); err != nil {
202-
return err
208+
if owner != "" {
209+
if err := pgLockRole(txn, owner); err != nil {
210+
return err
211+
}
212+
if err := withRolesGranted(txn, []string{owner}, func() error {
213+
return revokeRoleDefaultPrivileges(txn, d)
214+
}); err != nil {
215+
return err
216+
}
203217
}
204218

205219
if err := txn.Commit(); err != nil {
@@ -215,9 +229,10 @@ func readRoleDefaultPrivileges(txn *sql.Tx, d *schema.ResourceData) error {
215229
pgSchema := d.Get("schema").(string)
216230
objectType := d.Get("object_type").(string)
217231
privilegesInput := d.Get("privileges").(*schema.Set).List()
218-
219-
if err := pgLockRole(txn, owner); err != nil {
220-
return err
232+
if owner != "" {
233+
if err := pgLockRole(txn, owner); err != nil {
234+
return err
235+
}
221236
}
222237

223238
roleOID, err := getRoleOID(txn, role)
@@ -228,7 +243,7 @@ func readRoleDefaultPrivileges(txn *sql.Tx, d *schema.ResourceData) error {
228243
var query string
229244
var queryArgs []interface{}
230245

231-
if pgSchema != "" {
246+
if pgSchema != "" && owner != "" {
232247
query = `SELECT array_agg(prtype) FROM (
233248
SELECT defaclnamespace, (aclexplode(defaclacl)).* FROM pg_default_acl
234249
WHERE defaclobjtype = $3
@@ -237,14 +252,31 @@ func readRoleDefaultPrivileges(txn *sql.Tx, d *schema.ResourceData) error {
237252
WHERE grantee_oid = $1 AND nspname = $2 AND pg_get_userbyid(grantor_oid) = $4;
238253
`
239254
queryArgs = []interface{}{roleOID, pgSchema, objectTypes[objectType], owner}
240-
} else {
255+
} else if owner != "" {
241256
query = `SELECT array_agg(prtype) FROM (
242257
SELECT defaclnamespace, (aclexplode(defaclacl)).* FROM pg_default_acl
243258
WHERE defaclobjtype = $2
244259
) AS t (namespace, grantor_oid, grantee_oid, prtype, grantable)
245260
WHERE grantee_oid = $1 AND namespace = 0 AND pg_get_userbyid(grantor_oid) = $3;
246261
`
247262
queryArgs = []interface{}{roleOID, objectTypes[objectType], owner}
263+
} else if pgSchema != "" {
264+
query = `SELECT array_agg(prtype) FROM (
265+
SELECT defaclnamespace, (aclexplode(defaclacl)).* FROM pg_default_acl
266+
WHERE defaclobjtype = $3
267+
) AS t (namespace, grantor_oid, grantee_oid, prtype, grantable)
268+
JOIN pg_namespace ON pg_namespace.oid = namespace
269+
WHERE grantee_oid = $1 AND nspname = $2;
270+
`
271+
queryArgs = []interface{}{roleOID, pgSchema, objectTypes[objectType]}
272+
} else {
273+
query = `SELECT array_agg(prtype) FROM (
274+
SELECT defaclnamespace, (aclexplode(defaclacl)).* FROM pg_default_acl
275+
WHERE defaclobjtype = $2
276+
) AS t (namespace, grantor_oid, grantee_oid, prtype, grantable)
277+
WHERE grantee_oid = $1 AND namespace = 0;
278+
`
279+
queryArgs = []interface{}{roleOID, objectTypes[objectType]}
248280
}
249281

250282
// This query aggregates the list of default privileges type (prtype)
@@ -288,21 +320,19 @@ func grantRoleDefaultPrivileges(txn *sql.Tx, d *schema.ResourceData) error {
288320
}
289321

290322
if len(privileges) == 0 {
291-
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))
323+
log.Printf("[DEBUG] no default privileges to grant for role %s, owner %s in database: %s,", role, d.Get("owner").(string), d.Get("database").(string))
292324
return nil
293325
}
294326

295327
var inSchema string
296-
297-
// If a schema is specified we need to build the part of the query string to action this
298328
if pgSchema != "" {
299329
inSchema = fmt.Sprintf("IN SCHEMA %s", pq.QuoteIdentifier(pgSchema))
300330
}
301331

302-
// If an owner is specified, build the query string to include it
332+
// Handle owner logic only if owner is not empty
303333
var forOwner string
304-
if d.Get("owner").(string) != "" {
305-
forOwner = fmt.Sprintf("FOR ROLE %s", pq.QuoteIdentifier(d.Get("owner").(string)))
334+
if owner := d.Get("owner").(string); owner != "" {
335+
forOwner = fmt.Sprintf("FOR ROLE %s", pq.QuoteIdentifier(owner))
306336
}
307337

308338
query := fmt.Sprintf("ALTER DEFAULT PRIVILEGES %s %s GRANT %s ON %sS TO %s",
@@ -317,9 +347,7 @@ func grantRoleDefaultPrivileges(txn *sql.Tx, d *schema.ResourceData) error {
317347
query = query + " WITH GRANT OPTION"
318348
}
319349

320-
_, err := txn.Exec(
321-
query,
322-
)
350+
_, err := txn.Exec(query)
323351
if err != nil {
324352
return fmt.Errorf("could not alter default privileges: %w", err)
325353
}
@@ -331,14 +359,18 @@ func revokeRoleDefaultPrivileges(txn *sql.Tx, d *schema.ResourceData) error {
331359
pgSchema := d.Get("schema").(string)
332360

333361
var inSchema string
334-
335-
// If a schema is specified we need to build the part of the query string to action this
336362
if pgSchema != "" {
337363
inSchema = fmt.Sprintf("IN SCHEMA %s", pq.QuoteIdentifier(pgSchema))
338364
}
365+
366+
var forOwner string
367+
if owner := d.Get("owner").(string); owner != "" {
368+
forOwner = fmt.Sprintf("FOR ROLE %s", pq.QuoteIdentifier(owner))
369+
}
370+
339371
query := fmt.Sprintf(
340-
"ALTER DEFAULT PRIVILEGES FOR ROLE %s %s REVOKE ALL ON %sS FROM %s",
341-
pq.QuoteIdentifier(d.Get("owner").(string)),
372+
"ALTER DEFAULT PRIVILEGES %s %s REVOKE ALL ON %sS FROM %s",
373+
forOwner,
342374
inSchema,
343375
strings.ToUpper(d.Get("object_type").(string)),
344376
pq.QuoteIdentifier(d.Get("role").(string)),
@@ -356,9 +388,14 @@ func generateDefaultPrivilegesID(d *schema.ResourceData) string {
356388
pgSchema = "noschema"
357389
}
358390

391+
// If owner is empty, exclude it from the ID
392+
var owner string
393+
if owner = d.Get("owner").(string); owner == "" {
394+
owner = "noowner"
395+
}
396+
359397
return strings.Join([]string{
360398
d.Get("role").(string), d.Get("database").(string), pgSchema,
361-
d.Get("owner").(string), d.Get("object_type").(string),
399+
owner, d.Get("object_type").(string),
362400
}, "_")
363-
364401
}

0 commit comments

Comments
 (0)