-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP added is_google_cloud to version info for issue #12 #40
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,12 +4,10 @@ | |
|
||
from pgbedrock import common | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
Q_GET_ALL_CURRENT_DEFAULTS = """ | ||
WITH relkind_mapping (objkey, objkind) AS ( | ||
WITH relkind_mapping (objkey, objkind) AS ( | ||
VALUES ('f', 'functions'), | ||
('r', 'tables'), | ||
('S', 'sequences'), | ||
|
@@ -24,7 +22,7 @@ | |
(aclexplode(def.defaclacl)).privilege_type | ||
FROM | ||
pg_default_acl def | ||
JOIN pg_authid auth | ||
JOIN {roles_table} auth | ||
ON def.defaclrole = auth.oid | ||
JOIN pg_namespace nsp | ||
ON def.defaclnamespace = nsp.oid | ||
|
@@ -41,7 +39,7 @@ | |
subq.privilege_type | ||
FROM | ||
subq | ||
JOIN pg_authid t_grantee | ||
JOIN {roles_table} t_grantee | ||
ON subq.grantee_oid = t_grantee.oid | ||
WHERE | ||
subq.grantor_oid != subq.grantee_oid | ||
|
@@ -66,14 +64,14 @@ | |
(aclexplode(c.relacl)).privilege_type | ||
FROM | ||
pg_class c | ||
JOIN pg_authid t_owner | ||
JOIN {roles_table} t_owner | ||
ON c.relowner = t_owner.OID | ||
JOIN pg_namespace nsp | ||
ON c.relnamespace = nsp.oid | ||
JOIN relkind_mapping map | ||
ON c.relkind = map.objkey | ||
WHERE | ||
nsp.nspname NOT LIKE 'pg\_t%' | ||
nsp.nspname NOT LIKE 'pg\_t%%' | ||
AND c.relacl IS NOT NULL | ||
), schemas AS ( | ||
SELECT | ||
|
@@ -83,7 +81,7 @@ | |
t_owner.rolname AS owner, | ||
(aclexplode(nsp.nspacl)).privilege_type | ||
FROM pg_namespace nsp | ||
JOIN pg_authid t_owner | ||
JOIN {roles_table} t_owner | ||
ON nsp.nspowner = t_owner.OID | ||
), combined AS ( | ||
SELECT * | ||
|
@@ -99,7 +97,7 @@ | |
combined.privilege_type | ||
FROM | ||
combined | ||
JOIN pg_authid t_grantee | ||
JOIN {roles_table} t_grantee | ||
ON combined.grantee_oid = t_grantee.oid | ||
WHERE combined.owner != t_grantee.rolname | ||
; | ||
|
@@ -118,7 +116,7 @@ | |
rolreplication, | ||
rolsuper, | ||
rolvaliduntil | ||
FROM pg_authid | ||
FROM {roles_table} | ||
WHERE rolname != 'pg_signal_backend' | ||
; | ||
""" | ||
|
@@ -129,9 +127,9 @@ | |
auth_group.rolname AS group | ||
FROM | ||
pg_auth_members link_table | ||
JOIN pg_authid auth_member | ||
JOIN {roles_table} auth_member | ||
ON link_table.member = auth_member.oid | ||
JOIN pg_authid auth_group | ||
JOIN {roles_table} auth_group | ||
ON link_table.roleid = auth_group.oid | ||
; | ||
""" | ||
|
@@ -190,17 +188,17 @@ | |
t_owner.rolname AS owner, | ||
co.is_dependent | ||
FROM combined AS co | ||
JOIN pg_authid t_owner | ||
JOIN {roles_table} t_owner | ||
ON co.owner_id = t_owner.OID | ||
WHERE | ||
co.schema NOT LIKE 'pg\_t%' | ||
co.schema NOT LIKE 'pg\_t%%' | ||
; | ||
""" | ||
|
||
Q_GET_ALL_PERSONAL_SCHEMAS = """ | ||
SELECT nsp.nspname | ||
FROM pg_namespace nsp | ||
JOIN pg_authid auth | ||
JOIN {roles_table} auth | ||
ON nsp.nspname = auth.rolname | ||
WHERE auth.rolcanlogin IS TRUE | ||
; | ||
|
@@ -210,7 +208,8 @@ | |
SELECT | ||
substring(version from 'PostgreSQL ([0-9.]*) ') AS postgres_version, | ||
substring(version from 'Redshift ([0-9.]*)') AS redshift_version, | ||
version LIKE '%Redshift%' AS is_redshift | ||
version LIKE '%Redshift%' AS is_redshift, | ||
exists(SELECT * FROM pg_roles WHERE rolname = 'cloudsqladmin') AS is_google_cloud | ||
FROM version() | ||
; | ||
""" | ||
|
@@ -219,23 +218,23 @@ | |
# don't add things like SELECT for tables into the write privileges | ||
PRIVILEGE_MAP = { | ||
'tables': | ||
{'read': ('SELECT', ), | ||
{'read': ('SELECT',), | ||
'write': ('INSERT', 'UPDATE', 'DELETE', 'TRUNCATE', 'REFERENCES', 'TRIGGER') | ||
}, | ||
'sequences': | ||
{'read': ('SELECT', ), | ||
{'read': ('SELECT',), | ||
'write': ('USAGE', 'UPDATE') | ||
}, | ||
'schemas': | ||
{'read': ('USAGE', ), | ||
'write': ('CREATE', ) | ||
{'read': ('USAGE',), | ||
'write': ('CREATE',) | ||
}, | ||
} | ||
|
||
ObjectInfo = namedtuple('ObjectInfo', ['kind', 'name', 'owner', 'is_dependent']) | ||
ObjectAttributes = namedtuple('ObjectAttributes', | ||
['kind', 'schema', 'name', 'owner', 'is_dependent']) | ||
VersionInfo = namedtuple('VersionInfo', ['postgres_version', 'redshift_version', 'is_redshift']) | ||
VersionInfo = namedtuple('VersionInfo', ['postgres_version', 'redshift_version', 'is_redshift', 'is_google_cloud']) | ||
|
||
|
||
class DatabaseContext(object): | ||
|
@@ -259,6 +258,11 @@ def __init__(self, cursor, verbose): | |
self.cursor = cursor | ||
self.verbose = verbose | ||
self._cache = dict() | ||
version_info = self.get_version_info() | ||
if version_info.is_google_cloud: | ||
self.query_context = {'roles_table': 'pg_roles'} | ||
else: | ||
self.query_context = {'roles_table': 'pg_authid'} | ||
|
||
def __getattribute__(self, attr): | ||
""" If the requested attribute should be cached and hasn't, fetch it and cache it. """ | ||
|
@@ -302,7 +306,7 @@ def get_all_current_defaults(self): | |
""" | ||
DefaultRow = namedtuple('DefaultRow', | ||
['grantee', 'objkind', 'grantor', 'schema', 'privilege']) | ||
common.run_query(self.cursor, self.verbose, Q_GET_ALL_CURRENT_DEFAULTS) | ||
common.run_query(self.cursor, self.verbose, Q_GET_ALL_CURRENT_DEFAULTS.format(**self.query_context)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If there end up being more than one thing we have to change to get the queries to work, I can see having a container for all those variables (e.g. |
||
|
||
current_defaults = defaultdict(dict) | ||
for i in self.cursor.fetchall(): | ||
|
@@ -376,7 +380,7 @@ def get_all_current_nondefaults(self): | |
""" | ||
NonDefaultRow = namedtuple('NonDefaultRow', | ||
['grantee', 'objkind', 'objname', 'privilege']) | ||
common.run_query(self.cursor, self.verbose, Q_GET_ALL_CURRENT_NONDEFAULTS) | ||
common.run_query(self.cursor, self.verbose, Q_GET_ALL_CURRENT_NONDEFAULTS.format(**self.query_context)) | ||
current_nondefaults = defaultdict(dict) | ||
|
||
for i in self.cursor.fetchall(): | ||
|
@@ -410,8 +414,9 @@ def get_role_current_nondefaults(self, rolename, object_kind, access): | |
return set() | ||
|
||
def get_all_role_attributes(self): | ||
""" Return a dict with key = rolname and values = all fields in pg_authid """ | ||
common.run_query(self.cursor, self.verbose, Q_GET_ALL_ROLE_ATTRIBUTES) | ||
""" Return a dict with key = rolname and values = all fields | ||
in roles_table identified by get_context() depending on the DB environment""" | ||
common.run_query(self.cursor, self.verbose, Q_GET_ALL_ROLE_ATTRIBUTES.format(**self.query_context)) | ||
role_attributes = {row['rolname']: dict(row) for row in self.cursor.fetchall()} | ||
return role_attributes | ||
|
||
|
@@ -430,7 +435,7 @@ def get_all_raw_object_attributes(self): | |
The results are used in several subsequent methods, so having consistent results is | ||
important. Thus, this helper method is here to ensure that we only run this query once. | ||
""" | ||
common.run_query(self.cursor, self.verbose, Q_GET_ALL_RAW_OBJECT_ATTRIBUTES) | ||
common.run_query(self.cursor, self.verbose, Q_GET_ALL_RAW_OBJECT_ATTRIBUTES.format(**self.query_context)) | ||
results = [ObjectAttributes(*row) for row in self.cursor.fetchall()] | ||
return results | ||
|
||
|
@@ -471,7 +476,7 @@ def get_all_object_attributes(self): | |
|
||
def get_all_memberships(self): | ||
""" Return a list of tuple, where each tuple is (member, group) """ | ||
common.run_query(self.cursor, self.verbose, Q_GET_ALL_MEMBERSHIPS) | ||
common.run_query(self.cursor, self.verbose, Q_GET_ALL_MEMBERSHIPS.format(**self.query_context)) | ||
return self.cursor.fetchall() | ||
|
||
def get_all_schemas_and_owners(self): | ||
|
@@ -492,7 +497,7 @@ def get_role_memberships(self, rolename): | |
|
||
def get_all_personal_schemas(self): | ||
""" Return all personal schemas as a set """ | ||
common.run_query(self.cursor, self.verbose, Q_GET_ALL_PERSONAL_SCHEMAS) | ||
common.run_query(self.cursor, self.verbose, Q_GET_ALL_PERSONAL_SCHEMAS.format(**self.query_context)) | ||
personal_schemas = set([i[0] for i in self.cursor.fetchall()]) | ||
return personal_schemas | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this double percent sign correct? I've never needed to do that anywhere else in pgbedrock, and the other uses of a percent sign within a query in this file weren't modified, which makes me wonder if this is a remnant of tinkering.