Skip to content

Commit f3a2427

Browse files
authored
Merge pull request #15 from Riskified/DEV-89026-system-privs
Dev 89026 system privs
2 parents 989f0f5 + 1686e84 commit f3a2427

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

postgresql/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ const (
5959
fetureRoleEncryptedPass
6060
featureAdvisoryXactLock
6161
featureTransactionIsolation
62+
featureSysPrivileges
6263
)
6364

6465
var (
@@ -154,6 +155,7 @@ var (
154155
featureAdvisoryXactLock: semver.MustParseRange(">=9.1.0"),
155156
//Postgresql do not support transaction isolation in Role level
156157
featureTransactionIsolation: semver.MustParseRange("<1.0.0"),
158+
featureSysPrivileges: semver.MustParseRange("<1.0.0"),
157159
}
158160

159161
// Mapping of feature flags to versions
@@ -266,6 +268,7 @@ var (
266268
featureAdvisoryXactLock: semver.MustParseRange("<1.0.0"),
267269

268270
featureTransactionIsolation: semver.MustParseRange(">=23.2.0"),
271+
featureSysPrivileges: semver.MustParseRange(">=22.2.0"),
269272
}
270273
)
271274

postgresql/helpers.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ func sliceContainsStr(haystack []string, needle string) bool {
236236
// allowedPrivileges is the list of privileges allowed per object types in Postgres.
237237
// see: https://www.postgresql.org/docs/current/sql-grant.html
238238
var allowedPrivileges = map[string][]string{
239+
"system": {"ALL", "BACKUP", "CANCELQUERY", "CONTROLJOB", "CREATEDB", "CREATELOGIN", "CREATEROLE", "EXTERNALCONNECTION", "EXTERNALIOIMPLICITACCESS", "MODIFYCLUSTERSETTING", "MODIFYSQLCLUSTERSETTING", "NOSQLLOGIN", "REPLICATION", "RESTORE", "VIEWACTIVITY", "VIEWACTIVITYREDACTED", "VIEWCLUSTERMETADATA", "VIEWCLUSTERSETTING", "VIEWDEBUG", "VIEWJOB", "VIEWSYSTEMTABLE"},
239240
"database": {"ALL", "CREATE", "CONNECT", "TEMPORARY", "BACKUP", "RESTORE", "ZONECONFIG"},
240241
"table": {"ALL", "SELECT", "INSERT", "UPDATE", "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER", "DROP", "CHANGEFEED", "RESTORE", "ZONECONFIG"},
241242
"sequence": {"ALL", "USAGE", "SELECT", "UPDATE", "CREATE", "DELETE", "INSERT", "ZONECONFIG"},

postgresql/resource_postgresql_grant.go

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
)
1515

1616
var allowedObjectTypes = []string{
17+
"system",
1718
"database",
1819
"function",
1920
"procedure",
@@ -255,6 +256,16 @@ func resourcePostgreSQLGrantDelete(db *DBConnection, d *schema.ResourceData) err
255256
return nil
256257
}
257258

259+
func readSystemRolePriviges(txn *sql.Tx, role string) error {
260+
var query string
261+
var privileges pq.ByteaArray
262+
query = fmt.Sprintf(`with a as (show system grants for %s) select array_agg(privilege_type) from a`, role)
263+
if err := txn.QueryRow(query).Scan(&privileges); err != nil {
264+
return fmt.Errorf("could not read system privileges: %w", err)
265+
}
266+
return nil
267+
}
268+
258269
func readDatabaseRolePriviges(txn *sql.Tx, db *DBConnection, d *schema.ResourceData, roleOID uint32, role string) error {
259270
dbName := d.Get("database").(string)
260271
var query string
@@ -443,6 +454,8 @@ func readRolePrivileges(txn *sql.Tx, db *DBConnection, d *schema.ResourceData) e
443454
var rows *sql.Rows
444455

445456
switch objectType {
457+
case "system":
458+
return readSystemRolePriviges(txn, role)
446459
case "database":
447460
return readDatabaseRolePriviges(txn, db, d, roleOID, role)
448461

@@ -547,6 +560,12 @@ func createGrantQuery(d *schema.ResourceData, privileges []string) string {
547560
var query string
548561

549562
switch strings.ToUpper(d.Get("object_type").(string)) {
563+
case "SYSTEM":
564+
query = fmt.Sprintf(
565+
"GRANT SYSTEM %s TO %s",
566+
strings.Join(privileges, ","),
567+
pq.QuoteIdentifier(d.Get("role").(string)),
568+
)
550569
case "DATABASE":
551570
query = fmt.Sprintf(
552571
"GRANT %s ON DATABASE %s TO %s",
@@ -618,6 +637,11 @@ func createRevokeQuery(d *schema.ResourceData) string {
618637
var query string
619638

620639
switch strings.ToUpper(d.Get("object_type").(string)) {
640+
case "SYSTEM":
641+
query = fmt.Sprintf(
642+
"REVOKE SYSTEM ALL FROM %s",
643+
pq.QuoteIdentifier(d.Get("role").(string)),
644+
)
621645
case "DATABASE":
622646
query = fmt.Sprintf(
623647
"REVOKE ALL PRIVILEGES ON DATABASE %s FROM %s",
@@ -839,19 +863,25 @@ func getRolesToGrant(txn *sql.Tx, d *schema.ResourceData) ([]string, error) {
839863
func validateFeatureSupport(db *DBConnection, d *schema.ResourceData) error {
840864
if !db.featureSupported(featurePrivileges) {
841865
return fmt.Errorf(
842-
"postgresql_grant resource is not supported for this Postgres version (%s)",
866+
"postgresql_grant resource is not supported for this version (%s)",
843867
db.version,
844868
)
845869
}
846870
if d.Get("object_type") == "procedure" && !db.featureSupported(featureProcedure) {
847871
return fmt.Errorf(
848-
"object type PROCEDURE is not supported for this Postgres version (%s)",
872+
"object type PROCEDURE is not supported for this version (%s)",
849873
db.version,
850874
)
851875
}
852876
if d.Get("object_type") == "routine" && !db.featureSupported(featureRoutine) {
853877
return fmt.Errorf(
854-
"object type ROUTINE is not supported for this Postgres version (%s)",
878+
"object type ROUTINE is not supported for this version (%s)",
879+
db.version,
880+
)
881+
}
882+
if d.Get("object_type") == "system" && !db.featureSupported(featureSysPrivileges) {
883+
return fmt.Errorf(
884+
"privelege type System is not supported for this version (%s)",
855885
db.version,
856886
)
857887
}

0 commit comments

Comments
 (0)