@@ -19,6 +19,8 @@ var allowedObjectTypes = []string{
1919 "schema" ,
2020 "sequence" ,
2121 "table" ,
22+ "foreign_data_wrapper" ,
23+ "foreign_server" ,
2224}
2325
2426var objectTypes = map [string ]string {
@@ -125,12 +127,15 @@ func resourcePostgreSQLGrantCreate(db *DBConnection, d *schema.ResourceData) err
125127
126128 // Validate parameters.
127129 objectType := d .Get ("object_type" ).(string )
128- if d .Get ("schema" ).(string ) == "" && objectType != "database" {
130+ if d .Get ("schema" ).(string ) == "" && ! sliceContainsStr ([] string { "database" , "foreign_data_wrapper" , "foreign_server" }, objectType ) {
129131 return fmt .Errorf ("parameter 'schema' is mandatory for postgresql_grant resource" )
130132 }
131133 if d .Get ("objects" ).(* schema.Set ).Len () > 0 && (objectType == "database" || objectType == "schema" ) {
132134 return fmt .Errorf ("cannot specify `objects` when `object_type` is `database` or `schema`" )
133135 }
136+ if d .Get ("objects" ).(* schema.Set ).Len () != 1 && (objectType == "foreign_data_wrapper" || objectType == "foreign_server" ) {
137+ return fmt .Errorf ("one element must be specified in `objects` when `object_type` is `foreign_data_wrapper` or `foreign_server`" )
138+ }
134139 if err := validatePrivileges (d ); err != nil {
135140 return err
136141 }
@@ -247,6 +252,46 @@ WHERE grantee = $2
247252 return nil
248253}
249254
255+ func readForeignDataWrapperRolePrivileges (txn * sql.Tx , d * schema.ResourceData , roleOID int ) error {
256+ objects := d .Get ("objects" ).(* schema.Set ).List ()
257+ fdwName := objects [0 ].(string )
258+ query := `
259+ SELECT pg_catalog.array_agg(privilege_type)
260+ FROM (
261+ SELECT (pg_catalog.aclexplode(fdwacl)).* FROM pg_catalog.pg_foreign_data_wrapper WHERE fdwname=$1
262+ ) as privileges
263+ WHERE grantee = $2
264+ `
265+
266+ var privileges pq.ByteaArray
267+ if err := txn .QueryRow (query , fdwName , roleOID ).Scan (& privileges ); err != nil {
268+ return fmt .Errorf ("could not read privileges for foreign data wrapper %s: %w" , fdwName , err )
269+ }
270+
271+ d .Set ("privileges" , pgArrayToSet (privileges ))
272+ return nil
273+ }
274+
275+ func readForeignServerRolePrivileges (txn * sql.Tx , d * schema.ResourceData , roleOID int ) error {
276+ objects := d .Get ("objects" ).(* schema.Set ).List ()
277+ srvName := objects [0 ].(string )
278+ query := `
279+ SELECT pg_catalog.array_agg(privilege_type)
280+ FROM (
281+ SELECT (pg_catalog.aclexplode(srvacl)).* FROM pg_catalog.pg_foreign_server WHERE srvname=$1
282+ ) as privileges
283+ WHERE grantee = $2
284+ `
285+
286+ var privileges pq.ByteaArray
287+ if err := txn .QueryRow (query , srvName , roleOID ).Scan (& privileges ); err != nil {
288+ return fmt .Errorf ("could not read privileges for foreign server %s: %w" , srvName , err )
289+ }
290+
291+ d .Set ("privileges" , pgArrayToSet (privileges ))
292+ return nil
293+ }
294+
250295func readRolePrivileges (txn * sql.Tx , d * schema.ResourceData ) error {
251296 role := d .Get ("role" ).(string )
252297 objectType := d .Get ("object_type" ).(string )
@@ -267,6 +312,12 @@ func readRolePrivileges(txn *sql.Tx, d *schema.ResourceData) error {
267312 case "schema" :
268313 return readSchemaRolePriviges (txn , d , roleOID )
269314
315+ case "foreign_data_wrapper" :
316+ return readForeignDataWrapperRolePrivileges (txn , d , roleOID )
317+
318+ case "foreign_server" :
319+ return readForeignServerRolePrivileges (txn , d , roleOID )
320+
270321 case "function" :
271322 query = `
272323SELECT pg_proc.proname, array_remove(array_agg(privilege_type), NULL)
@@ -363,6 +414,22 @@ func createGrantQuery(d *schema.ResourceData, privileges []string) string {
363414 pq .QuoteIdentifier (d .Get ("schema" ).(string )),
364415 pq .QuoteIdentifier (d .Get ("role" ).(string )),
365416 )
417+ case "FOREIGN_DATA_WRAPPER" :
418+ fdwName := d .Get ("objects" ).(* schema.Set ).List ()[0 ]
419+ query = fmt .Sprintf (
420+ "GRANT %s ON FOREIGN DATA WRAPPER %s TO %s" ,
421+ strings .Join (privileges , "," ),
422+ pq .QuoteIdentifier (fdwName .(string )),
423+ pq .QuoteIdentifier (d .Get ("role" ).(string )),
424+ )
425+ case "FOREIGN_SERVER" :
426+ srvName := d .Get ("objects" ).(* schema.Set ).List ()[0 ]
427+ query = fmt .Sprintf (
428+ "GRANT %s ON FOREIGN SERVER %s TO %s" ,
429+ strings .Join (privileges , "," ),
430+ pq .QuoteIdentifier (srvName .(string )),
431+ pq .QuoteIdentifier (d .Get ("role" ).(string )),
432+ )
366433 case "TABLE" , "SEQUENCE" , "FUNCTION" :
367434 objects := d .Get ("objects" ).(* schema.Set )
368435 if objects .Len () > 0 {
@@ -407,6 +474,20 @@ func createRevokeQuery(d *schema.ResourceData) string {
407474 pq .QuoteIdentifier (d .Get ("schema" ).(string )),
408475 pq .QuoteIdentifier (d .Get ("role" ).(string )),
409476 )
477+ case "FOREIGN_DATA_WRAPPER" :
478+ fdwName := d .Get ("objects" ).(* schema.Set ).List ()[0 ]
479+ query = fmt .Sprintf (
480+ "REVOKE ALL PRIVILEGES ON FOREIGN DATA WRAPPER %s FROM %s" ,
481+ pq .QuoteIdentifier (fdwName .(string )),
482+ pq .QuoteIdentifier (d .Get ("role" ).(string )),
483+ )
484+ case "FOREIGN_SERVER" :
485+ srvName := d .Get ("objects" ).(* schema.Set ).List ()[0 ]
486+ query = fmt .Sprintf (
487+ "REVOKE ALL PRIVILEGES ON FOREIGN SERVER %s FROM %s" ,
488+ pq .QuoteIdentifier (srvName .(string )),
489+ pq .QuoteIdentifier (d .Get ("role" ).(string )),
490+ )
410491 case "TABLE" , "SEQUENCE" , "FUNCTION" :
411492 objects := d .Get ("objects" ).(* schema.Set )
412493 if objects .Len () > 0 {
@@ -487,7 +568,7 @@ func checkRoleDBSchemaExists(client *Client, d *schema.ResourceData) (bool, erro
487568
488569 pgSchema := d .Get ("schema" ).(string )
489570
490- if d .Get ("object_type" ).(string ) != "database" && pgSchema != "" {
571+ if ! sliceContainsStr ([] string { "database" , "foreign_data_wrapper" , "foreign_server" }, d .Get ("object_type" ).(string )) && pgSchema != "" {
491572 // Connect on this database to check if schema exists
492573 dbTxn , err := startTransaction (client , database )
493574 if err != nil {
@@ -513,7 +594,7 @@ func generateGrantID(d *schema.ResourceData) string {
513594 parts := []string {d .Get ("role" ).(string ), d .Get ("database" ).(string )}
514595
515596 objectType := d .Get ("object_type" ).(string )
516- if objectType != "database" {
597+ if objectType != "database" && objectType != "foreign_data_wrapper" && objectType != "foreign_server" {
517598 parts = append (parts , d .Get ("schema" ).(string ))
518599 }
519600 parts = append (parts , objectType )
@@ -532,7 +613,7 @@ func getRolesToGrant(txn *sql.Tx, d *schema.ResourceData) ([]string, error) {
532613 owners := []string {}
533614 objectType := d .Get ("object_type" )
534615
535- if objectType == "database" {
616+ if objectType == "database" || objectType == "foreign_data_wrapper" || objectType == "foreign_server" {
536617 return owners , nil
537618 }
538619
0 commit comments