@@ -34,12 +34,12 @@ var objectTypes = map[string]string{
3434 "schema" : "n" ,
3535}
3636
37+ type ResourceSchemeGetter func (string ) interface {}
38+
3739func resourcePostgreSQLGrant () * schema.Resource {
3840 return & schema.Resource {
3941 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:
42+ Update : PGResourceFunc (resourcePostgreSQLGrantUpdate ),
4343 Read : PGResourceFunc (resourcePostgreSQLGrantRead ),
4444 Delete : PGResourceFunc (resourcePostgreSQLGrantDelete ),
4545
@@ -86,9 +86,9 @@ func resourcePostgreSQLGrant() *schema.Resource {
8686 Description : "The specific columns to grant privileges on for this role" ,
8787 },
8888 "privileges" : {
89- Type : schema .TypeSet ,
90- Required : true ,
91- ForceNew : true ,
89+ Type : schema .TypeSet ,
90+ Required : true ,
91+ // ForceNew: true,
9292 Elem : & schema.Schema {Type : schema .TypeString },
9393 Set : schema .HashString ,
9494 Description : "The list of privileges to grant" ,
@@ -129,6 +129,14 @@ func resourcePostgreSQLGrantRead(db *DBConnection, d *schema.ResourceData) error
129129}
130130
131131func resourcePostgreSQLGrantCreate (db * DBConnection , d * schema.ResourceData ) error {
132+ return resourcePostgreSQLGrantCreateOrUpdate (db , d , false )
133+ }
134+
135+ func resourcePostgreSQLGrantUpdate (db * DBConnection , d * schema.ResourceData ) error {
136+ return resourcePostgreSQLGrantCreateOrUpdate (db , d , true )
137+ }
138+
139+ func resourcePostgreSQLGrantCreateOrUpdate (db * DBConnection , d * schema.ResourceData , usePrevious bool ) error {
132140 if err := validateFeatureSupport (db , d ); err != nil {
133141 return fmt .Errorf ("feature is not supported: %v" , err )
134142 }
@@ -187,7 +195,7 @@ func resourcePostgreSQLGrantCreate(db *DBConnection, d *schema.ResourceData) err
187195 // Revoke all privileges before granting otherwise reducing privileges will not work.
188196 // We just have to revoke them in the same transaction so the role will not lost its
189197 // privileges between the revoke and grant statements.
190- if err := revokeRolePrivileges (txn , d ); err != nil {
198+ if err := revokeRolePrivileges (txn , d , usePrevious ); err != nil {
191199 return err
192200 }
193201 if err := grantRolePrivileges (txn , d ); err != nil {
@@ -243,7 +251,7 @@ func resourcePostgreSQLGrantDelete(db *DBConnection, d *schema.ResourceData) err
243251 }
244252
245253 if err := withRolesGranted (txn , owners , func () error {
246- return revokeRolePrivileges (txn , d )
254+ return revokeRolePrivileges (txn , d , false )
247255 }); err != nil {
248256 return err
249257 }
@@ -589,40 +597,40 @@ func createGrantQuery(d *schema.ResourceData, privileges []string) string {
589597 return query
590598}
591599
592- func createRevokeQuery (d * schema. ResourceData ) string {
600+ func createRevokeQuery (getter ResourceSchemeGetter ) 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 }
@@ -687,8 +695,21 @@ func grantRolePrivileges(txn *sql.Tx, d *schema.ResourceData) error {
687695 return err
688696}
689697
690- func revokeRolePrivileges (txn * sql.Tx , d * schema.ResourceData ) error {
691- query := createRevokeQuery (d )
698+ func revokeRolePrivileges (txn * sql.Tx , d * schema.ResourceData , usePrevious bool ) error {
699+ getter := d .Get
700+
701+ if usePrevious {
702+ getter = func (name string ) interface {} {
703+ if d .HasChange (name ) {
704+ old , _ := d .GetChange (name )
705+ return old
706+ }
707+
708+ return d .Get (name )
709+ }
710+ }
711+
712+ query := createRevokeQuery (getter )
692713 if len (query ) == 0 {
693714 // Query is empty, don't run anything
694715 return nil
0 commit comments