@@ -37,9 +37,7 @@ var objectTypes = map[string]string{
3737func resourcePostgreSQLGrant () * schema.Resource {
3838 return & schema.Resource {
3939 Create : PGResourceFunc (resourcePostgreSQLGrantCreate ),
40- // Since all of this resource's arguments force a recreation
41- // there's no need for an Update function
42- // Update:
40+ Update : PGResourceFunc (resourcePostgreSQLGrantUpdate ),
4341 Read : PGResourceFunc (resourcePostgreSQLGrantRead ),
4442 Delete : PGResourceFunc (resourcePostgreSQLGrantDelete ),
4543
@@ -57,46 +55,46 @@ func resourcePostgreSQLGrant() *schema.Resource {
5755 Description : "The database to grant privileges on for this role" ,
5856 },
5957 "schema" : {
60- Type : schema .TypeString ,
61- Optional : true ,
62- ForceNew : true ,
58+ Type : schema .TypeString ,
59+ Optional : true ,
60+ // ForceNew: true,
6361 Description : "The database schema to grant privileges on for this role" ,
6462 },
6563 "object_type" : {
66- Type : schema .TypeString ,
67- Required : true ,
68- ForceNew : true ,
64+ Type : schema .TypeString ,
65+ Required : true ,
66+ // ForceNew: true,
6967 ValidateFunc : validation .StringInSlice (allowedObjectTypes , false ),
7068 Description : "The PostgreSQL object type to grant the privileges on (one of: " + strings .Join (allowedObjectTypes , ", " ) + ")" ,
7169 },
7270 "objects" : {
73- Type : schema .TypeSet ,
74- Optional : true ,
75- ForceNew : true ,
71+ Type : schema .TypeSet ,
72+ Optional : true ,
73+ // ForceNew: true,
7674 Elem : & schema.Schema {Type : schema .TypeString },
7775 Set : schema .HashString ,
7876 Description : "The specific objects to grant privileges on for this role (empty means all objects of the requested type)" ,
7977 },
8078 "columns" : {
81- Type : schema .TypeSet ,
82- Optional : true ,
83- ForceNew : true ,
79+ Type : schema .TypeSet ,
80+ Optional : true ,
81+ // ForceNew: true,
8482 Elem : & schema.Schema {Type : schema .TypeString },
8583 Set : schema .HashString ,
8684 Description : "The specific columns to grant privileges on for this role" ,
8785 },
8886 "privileges" : {
89- Type : schema .TypeSet ,
90- Required : true ,
91- ForceNew : true ,
87+ Type : schema .TypeSet ,
88+ Required : true ,
89+ // ForceNew: true,
9290 Elem : & schema.Schema {Type : schema .TypeString },
9391 Set : schema .HashString ,
9492 Description : "The list of privileges to grant" ,
9593 },
9694 "with_grant_option" : {
97- Type : schema .TypeBool ,
98- Optional : true ,
99- ForceNew : true ,
95+ Type : schema .TypeBool ,
96+ Optional : true ,
97+ // ForceNew: true,
10098 Default : false ,
10199 Description : "Permit the grant recipient to grant it to others" ,
102100 },
@@ -129,6 +127,10 @@ func resourcePostgreSQLGrantRead(db *DBConnection, d *schema.ResourceData) error
129127}
130128
131129func resourcePostgreSQLGrantCreate (db * DBConnection , d * schema.ResourceData ) error {
130+ return resourcePostgreSQLGrantCreateOrUpdate (db , d , false )
131+ }
132+
133+ func resourcePostgreSQLGrantCreateOrUpdate (db * DBConnection , d * schema.ResourceData , usePreviousForRevoke bool ) error {
132134 if err := validateFeatureSupport (db , d ); err != nil {
133135 return fmt .Errorf ("feature is not supported: %v" , err )
134136 }
@@ -187,7 +189,7 @@ func resourcePostgreSQLGrantCreate(db *DBConnection, d *schema.ResourceData) err
187189 // Revoke all privileges before granting otherwise reducing privileges will not work.
188190 // We just have to revoke them in the same transaction so the role will not lost its
189191 // privileges between the revoke and grant statements.
190- if err := revokeRolePrivileges (txn , d ); err != nil {
192+ if err := revokeRolePrivileges (txn , d , usePreviousForRevoke ); err != nil {
191193 return err
192194 }
193195 if err := grantRolePrivileges (txn , d ); err != nil {
@@ -213,6 +215,10 @@ func resourcePostgreSQLGrantCreate(db *DBConnection, d *schema.ResourceData) err
213215 return readRolePrivileges (txn , d )
214216}
215217
218+ func resourcePostgreSQLGrantUpdate (db * DBConnection , d * schema.ResourceData ) error {
219+ return resourcePostgreSQLGrantCreateOrUpdate (db , d , true )
220+ }
221+
216222func resourcePostgreSQLGrantDelete (db * DBConnection , d * schema.ResourceData ) error {
217223 if err := validateFeatureSupport (db , d ); err != nil {
218224 return fmt .Errorf ("feature is not supported: %v" , err )
@@ -243,7 +249,7 @@ func resourcePostgreSQLGrantDelete(db *DBConnection, d *schema.ResourceData) err
243249 }
244250
245251 if err := withRolesGranted (txn , owners , func () error {
246- return revokeRolePrivileges (txn , d )
252+ return revokeRolePrivileges (txn , d , false )
247253 }); err != nil {
248254 return err
249255 }
@@ -589,40 +595,42 @@ func createGrantQuery(d *schema.ResourceData, privileges []string) string {
589595 return query
590596}
591597
592- func createRevokeQuery (d * schema.ResourceData ) string {
598+ type ResourceSchemGetter func (string ) interface {}
599+
600+ func createRevokeQuery (getter ResourceSchemGetter ) string {
593601 var query string
594602
595- switch strings .ToUpper (d . Get ("object_type" ).(string )) {
603+ switch strings .ToUpper (getter ("object_type" ).(string )) {
596604 case "DATABASE" :
597605 query = fmt .Sprintf (
598606 "REVOKE ALL PRIVILEGES ON DATABASE %s FROM %s" ,
599- pq .QuoteIdentifier (d . Get ("database" ).(string )),
600- pq .QuoteIdentifier (d . Get ("role" ).(string )),
607+ pq .QuoteIdentifier (getter ("database" ).(string )),
608+ pq .QuoteIdentifier (getter ("role" ).(string )),
601609 )
602610 case "SCHEMA" :
603611 query = fmt .Sprintf (
604612 "REVOKE ALL PRIVILEGES ON SCHEMA %s FROM %s" ,
605- pq .QuoteIdentifier (d . Get ("schema" ).(string )),
606- pq .QuoteIdentifier (d . Get ("role" ).(string )),
613+ pq .QuoteIdentifier (getter ("schema" ).(string )),
614+ pq .QuoteIdentifier (getter ("role" ).(string )),
607615 )
608616 case "FOREIGN_DATA_WRAPPER" :
609- fdwName := d . Get ("objects" ).(* schema.Set ).List ()[0 ]
617+ fdwName := getter ("objects" ).(* schema.Set ).List ()[0 ]
610618 query = fmt .Sprintf (
611619 "REVOKE ALL PRIVILEGES ON FOREIGN DATA WRAPPER %s FROM %s" ,
612620 pq .QuoteIdentifier (fdwName .(string )),
613- pq .QuoteIdentifier (d . Get ("role" ).(string )),
621+ pq .QuoteIdentifier (getter ("role" ).(string )),
614622 )
615623 case "FOREIGN_SERVER" :
616- srvName := d . Get ("objects" ).(* schema.Set ).List ()[0 ]
624+ srvName := getter ("objects" ).(* schema.Set ).List ()[0 ]
617625 query = fmt .Sprintf (
618626 "REVOKE ALL PRIVILEGES ON FOREIGN SERVER %s FROM %s" ,
619627 pq .QuoteIdentifier (srvName .(string )),
620- pq .QuoteIdentifier (d . Get ("role" ).(string )),
628+ pq .QuoteIdentifier (getter ("role" ).(string )),
621629 )
622630 case "COLUMN" :
623- objects := d . Get ("objects" ).(* schema.Set )
624- columns := d . Get ("columns" ).(* schema.Set )
625- privileges := d . Get ("privileges" ).(* schema.Set )
631+ objects := getter ("objects" ).(* schema.Set )
632+ columns := getter ("columns" ).(* schema.Set )
633+ privileges := getter ("privileges" ).(* schema.Set )
626634 if privileges .Len () == 0 || columns .Len () == 0 {
627635 // No privileges to revoke, so don't revoke anything
628636 query = "SELECT NULL"
@@ -631,38 +639,38 @@ func createRevokeQuery(d *schema.ResourceData) string {
631639 "REVOKE %s (%s) ON TABLE %s FROM %s" ,
632640 setToPgIdentSimpleList (privileges ),
633641 setToPgIdentListWithoutSchema (columns ),
634- setToPgIdentList (d . Get ("schema" ).(string ), objects ),
635- pq .QuoteIdentifier (d . Get ("role" ).(string )),
642+ setToPgIdentList (getter ("schema" ).(string ), objects ),
643+ pq .QuoteIdentifier (getter ("role" ).(string )),
636644 )
637645 }
638646 case "TABLE" , "SEQUENCE" , "FUNCTION" , "PROCEDURE" , "ROUTINE" :
639- objects := d . Get ("objects" ).(* schema.Set )
640- privileges := d . Get ("privileges" ).(* schema.Set )
647+ objects := getter ("objects" ).(* schema.Set )
648+ privileges := getter ("privileges" ).(* schema.Set )
641649 if objects .Len () > 0 {
642650 if privileges .Len () > 0 {
643651 // Revoking specific privileges instead of all privileges
644652 // to avoid messing with column level grants
645653 query = fmt .Sprintf (
646654 "REVOKE %s ON %s %s FROM %s" ,
647655 setToPgIdentSimpleList (privileges ),
648- strings .ToUpper (d . Get ("object_type" ).(string )),
649- setToPgIdentList (d . Get ("schema" ).(string ), objects ),
650- pq .QuoteIdentifier (d . Get ("role" ).(string )),
656+ strings .ToUpper (getter ("object_type" ).(string )),
657+ setToPgIdentList (getter ("schema" ).(string ), objects ),
658+ pq .QuoteIdentifier (getter ("role" ).(string )),
651659 )
652660 } else {
653661 query = fmt .Sprintf (
654662 "REVOKE ALL PRIVILEGES ON %s %s FROM %s" ,
655- strings .ToUpper (d . Get ("object_type" ).(string )),
656- setToPgIdentList (d . Get ("schema" ).(string ), objects ),
657- pq .QuoteIdentifier (d . Get ("role" ).(string )),
663+ strings .ToUpper (getter ("object_type" ).(string )),
664+ setToPgIdentList (getter ("schema" ).(string ), objects ),
665+ pq .QuoteIdentifier (getter ("role" ).(string )),
658666 )
659667 }
660668 } else {
661669 query = fmt .Sprintf (
662670 "REVOKE ALL PRIVILEGES ON ALL %sS IN SCHEMA %s FROM %s" ,
663- strings .ToUpper (d . Get ("object_type" ).(string )),
664- pq .QuoteIdentifier (d . Get ("schema" ).(string )),
665- pq .QuoteIdentifier (d . Get ("role" ).(string )),
671+ strings .ToUpper (getter ("object_type" ).(string )),
672+ pq .QuoteIdentifier (getter ("schema" ).(string )),
673+ pq .QuoteIdentifier (getter ("role" ).(string )),
666674 )
667675 }
668676 }
@@ -675,24 +683,35 @@ func grantRolePrivileges(txn *sql.Tx, d *schema.ResourceData) error {
675683 for _ , priv := range d .Get ("privileges" ).(* schema.Set ).List () {
676684 privileges = append (privileges , priv .(string ))
677685 }
678-
679686 if len (privileges ) == 0 {
680687 log .Printf ("[DEBUG] no privileges to grant for role %s in database: %s," , d .Get ("role" ).(string ), d .Get ("database" ))
681688 return nil
682689 }
683-
684690 query := createGrantQuery (d , privileges )
691+ log .Printf ("[INFO] executing %s" , query )
685692
686693 _ , err := txn .Exec (query )
687694 return err
688695}
689696
690- func revokeRolePrivileges (txn * sql.Tx , d * schema.ResourceData ) error {
691- query := createRevokeQuery (d )
697+ func revokeRolePrivileges (txn * sql.Tx , d * schema.ResourceData , usePrevious bool ) error {
698+ var getter ResourceSchemGetter
699+ if usePrevious {
700+ getter = func (name string ) interface {} {
701+ old , _ := d .GetChange (name )
702+ return old
703+ }
704+ } else {
705+ getter = func (name string ) interface {} {
706+ return d .Get (name )
707+ }
708+ }
709+ query := createRevokeQuery (getter )
692710 if len (query ) == 0 {
693711 // Query is empty, don't run anything
694712 return nil
695713 }
714+ log .Printf ("[INFO] executing %s" , query )
696715 if _ , err := txn .Exec (query ); err != nil {
697716 return fmt .Errorf ("could not execute revoke query: %w" , err )
698717 }
0 commit comments