@@ -37,9 +37,7 @@ var objectTypes = map[string]string{
37
37
func resourcePostgreSQLGrant () * schema.Resource {
38
38
return & schema.Resource {
39
39
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 ),
43
41
Read : PGResourceFunc (resourcePostgreSQLGrantRead ),
44
42
Delete : PGResourceFunc (resourcePostgreSQLGrantDelete ),
45
43
@@ -57,46 +55,46 @@ func resourcePostgreSQLGrant() *schema.Resource {
57
55
Description : "The database to grant privileges on for this role" ,
58
56
},
59
57
"schema" : {
60
- Type : schema .TypeString ,
61
- Optional : true ,
62
- ForceNew : true ,
58
+ Type : schema .TypeString ,
59
+ Optional : true ,
60
+ // ForceNew: true,
63
61
Description : "The database schema to grant privileges on for this role" ,
64
62
},
65
63
"object_type" : {
66
- Type : schema .TypeString ,
67
- Required : true ,
68
- ForceNew : true ,
64
+ Type : schema .TypeString ,
65
+ Required : true ,
66
+ // ForceNew: true,
69
67
ValidateFunc : validation .StringInSlice (allowedObjectTypes , false ),
70
68
Description : "The PostgreSQL object type to grant the privileges on (one of: " + strings .Join (allowedObjectTypes , ", " ) + ")" ,
71
69
},
72
70
"objects" : {
73
- Type : schema .TypeSet ,
74
- Optional : true ,
75
- ForceNew : true ,
71
+ Type : schema .TypeSet ,
72
+ Optional : true ,
73
+ // ForceNew: true,
76
74
Elem : & schema.Schema {Type : schema .TypeString },
77
75
Set : schema .HashString ,
78
76
Description : "The specific objects to grant privileges on for this role (empty means all objects of the requested type)" ,
79
77
},
80
78
"columns" : {
81
- Type : schema .TypeSet ,
82
- Optional : true ,
83
- ForceNew : true ,
79
+ Type : schema .TypeSet ,
80
+ Optional : true ,
81
+ // ForceNew: true,
84
82
Elem : & schema.Schema {Type : schema .TypeString },
85
83
Set : schema .HashString ,
86
84
Description : "The specific columns to grant privileges on for this role" ,
87
85
},
88
86
"privileges" : {
89
- Type : schema .TypeSet ,
90
- Required : true ,
91
- ForceNew : true ,
87
+ Type : schema .TypeSet ,
88
+ Required : true ,
89
+ // ForceNew: true,
92
90
Elem : & schema.Schema {Type : schema .TypeString },
93
91
Set : schema .HashString ,
94
92
Description : "The list of privileges to grant" ,
95
93
},
96
94
"with_grant_option" : {
97
- Type : schema .TypeBool ,
98
- Optional : true ,
99
- ForceNew : true ,
95
+ Type : schema .TypeBool ,
96
+ Optional : true ,
97
+ // ForceNew: true,
100
98
Default : false ,
101
99
Description : "Permit the grant recipient to grant it to others" ,
102
100
},
@@ -129,6 +127,10 @@ func resourcePostgreSQLGrantRead(db *DBConnection, d *schema.ResourceData) error
129
127
}
130
128
131
129
func 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 {
132
134
if err := validateFeatureSupport (db , d ); err != nil {
133
135
return fmt .Errorf ("feature is not supported: %v" , err )
134
136
}
@@ -187,7 +189,7 @@ func resourcePostgreSQLGrantCreate(db *DBConnection, d *schema.ResourceData) err
187
189
// Revoke all privileges before granting otherwise reducing privileges will not work.
188
190
// We just have to revoke them in the same transaction so the role will not lost its
189
191
// privileges between the revoke and grant statements.
190
- if err := revokeRolePrivileges (txn , d ); err != nil {
192
+ if err := revokeRolePrivileges (txn , d , usePreviousForRevoke ); err != nil {
191
193
return err
192
194
}
193
195
if err := grantRolePrivileges (txn , d ); err != nil {
@@ -213,6 +215,10 @@ func resourcePostgreSQLGrantCreate(db *DBConnection, d *schema.ResourceData) err
213
215
return readRolePrivileges (txn , d )
214
216
}
215
217
218
+ func resourcePostgreSQLGrantUpdate (db * DBConnection , d * schema.ResourceData ) error {
219
+ return resourcePostgreSQLGrantCreateOrUpdate (db , d , true )
220
+ }
221
+
216
222
func resourcePostgreSQLGrantDelete (db * DBConnection , d * schema.ResourceData ) error {
217
223
if err := validateFeatureSupport (db , d ); err != nil {
218
224
return fmt .Errorf ("feature is not supported: %v" , err )
@@ -243,7 +249,7 @@ func resourcePostgreSQLGrantDelete(db *DBConnection, d *schema.ResourceData) err
243
249
}
244
250
245
251
if err := withRolesGranted (txn , owners , func () error {
246
- return revokeRolePrivileges (txn , d )
252
+ return revokeRolePrivileges (txn , d , false )
247
253
}); err != nil {
248
254
return err
249
255
}
@@ -589,40 +595,42 @@ func createGrantQuery(d *schema.ResourceData, privileges []string) string {
589
595
return query
590
596
}
591
597
592
- func createRevokeQuery (d * schema.ResourceData ) string {
598
+ type ResourceSchemGetter func (string ) interface {}
599
+
600
+ func createRevokeQuery (getter ResourceSchemGetter ) string {
593
601
var query string
594
602
595
- switch strings .ToUpper (d . Get ("object_type" ).(string )) {
603
+ switch strings .ToUpper (getter ("object_type" ).(string )) {
596
604
case "DATABASE" :
597
605
query = fmt .Sprintf (
598
606
"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 )),
601
609
)
602
610
case "SCHEMA" :
603
611
query = fmt .Sprintf (
604
612
"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 )),
607
615
)
608
616
case "FOREIGN_DATA_WRAPPER" :
609
- fdwName := d . Get ("objects" ).(* schema.Set ).List ()[0 ]
617
+ fdwName := getter ("objects" ).(* schema.Set ).List ()[0 ]
610
618
query = fmt .Sprintf (
611
619
"REVOKE ALL PRIVILEGES ON FOREIGN DATA WRAPPER %s FROM %s" ,
612
620
pq .QuoteIdentifier (fdwName .(string )),
613
- pq .QuoteIdentifier (d . Get ("role" ).(string )),
621
+ pq .QuoteIdentifier (getter ("role" ).(string )),
614
622
)
615
623
case "FOREIGN_SERVER" :
616
- srvName := d . Get ("objects" ).(* schema.Set ).List ()[0 ]
624
+ srvName := getter ("objects" ).(* schema.Set ).List ()[0 ]
617
625
query = fmt .Sprintf (
618
626
"REVOKE ALL PRIVILEGES ON FOREIGN SERVER %s FROM %s" ,
619
627
pq .QuoteIdentifier (srvName .(string )),
620
- pq .QuoteIdentifier (d . Get ("role" ).(string )),
628
+ pq .QuoteIdentifier (getter ("role" ).(string )),
621
629
)
622
630
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 )
626
634
if privileges .Len () == 0 || columns .Len () == 0 {
627
635
// No privileges to revoke, so don't revoke anything
628
636
query = "SELECT NULL"
@@ -631,38 +639,38 @@ func createRevokeQuery(d *schema.ResourceData) string {
631
639
"REVOKE %s (%s) ON TABLE %s FROM %s" ,
632
640
setToPgIdentSimpleList (privileges ),
633
641
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 )),
636
644
)
637
645
}
638
646
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 )
641
649
if objects .Len () > 0 {
642
650
if privileges .Len () > 0 {
643
651
// Revoking specific privileges instead of all privileges
644
652
// to avoid messing with column level grants
645
653
query = fmt .Sprintf (
646
654
"REVOKE %s ON %s %s FROM %s" ,
647
655
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 )),
651
659
)
652
660
} else {
653
661
query = fmt .Sprintf (
654
662
"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 )),
658
666
)
659
667
}
660
668
} else {
661
669
query = fmt .Sprintf (
662
670
"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 )),
666
674
)
667
675
}
668
676
}
@@ -675,24 +683,35 @@ func grantRolePrivileges(txn *sql.Tx, d *schema.ResourceData) error {
675
683
for _ , priv := range d .Get ("privileges" ).(* schema.Set ).List () {
676
684
privileges = append (privileges , priv .(string ))
677
685
}
678
-
679
686
if len (privileges ) == 0 {
680
687
log .Printf ("[DEBUG] no privileges to grant for role %s in database: %s," , d .Get ("role" ).(string ), d .Get ("database" ))
681
688
return nil
682
689
}
683
-
684
690
query := createGrantQuery (d , privileges )
691
+ log .Printf ("[INFO] executing %s" , query )
685
692
686
693
_ , err := txn .Exec (query )
687
694
return err
688
695
}
689
696
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 )
692
710
if len (query ) == 0 {
693
711
// Query is empty, don't run anything
694
712
return nil
695
713
}
714
+ log .Printf ("[INFO] executing %s" , query )
696
715
if _ , err := txn .Exec (query ); err != nil {
697
716
return fmt .Errorf ("could not execute revoke query: %w" , err )
698
717
}
0 commit comments