From cdd8d0fe1d47c21909d2d419d9c6a77a700d768d Mon Sep 17 00:00:00 2001 From: Peter Kosztolanyi Date: Sun, 14 Oct 2018 00:23:39 +0100 Subject: [PATCH 1/3] Optionally grant SELECT to roles automatically on newly created schemas and tables --- target_postgres/db_sync.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/target_postgres/db_sync.py b/target_postgres/db_sync.py index 4fba051..e986309 100644 --- a/target_postgres/db_sync.py +++ b/target_postgres/db_sync.py @@ -257,6 +257,23 @@ def create_table_query(self, is_temporary=False): ', '.join(columns + primary_key) ) + def grant_usage_on_schema(self, schema_name, grantee): + query = "GRANT USAGE ON SCHEMA {} TO GROUP {}".format(schema_name, grantee) + logger.info("Granting USAGE privilegue on '{}' schema to '{}'... {}".format(schema_name, grantee, query)) + self.query(query) + + def grant_select_on_all_tables_in_schema(self, schema_name, grantee): + query = "GRANT SELECT ON ALL TABLES IN SCHEMA {} TO GROUP {}".format(schema_name, grantee) + logger.info("Granting SELECT ON ALL TABLES privilegue on '{}' schema to '{}'... {}".format(schema_name, grantee, query)) + self.query(query) + + def grant_privilege(self, schema, grantees, grant_method): + if isinstance(grantees, list): + for grantee in grantees: + grant_method(schema, grantee) + elif isinstance(grantees, str): + grant_method(schema, grantees) + def create_schema_if_not_exists(self): schema_name = self.connection_config['schema'] schema_rows = self.query( @@ -267,6 +284,10 @@ def create_schema_if_not_exists(self): if len(schema_rows) == 0: self.query("CREATE SCHEMA IF NOT EXISTS {}".format(schema_name)) + if 'grant_select_to' in self.connection_config: + grant_select_to = self.connection_config['grant_select_to'] + self.grant_privilege(schema_name, grant_select_to, self.grant_usage_on_schema) + def get_tables(self): return self.query( 'SELECT table_name FROM information_schema.tables WHERE table_schema = %s', @@ -328,6 +349,10 @@ def sync_table(self): query = self.create_table_query() logger.info("Table '{}' does not exist. Creating... {}".format(stream, query)) self.query(query) + + if 'grant_select_to' in self.connection_config: + grant_select_to = self.connection_config['grant_select_to'] + self.grant_privilege(self.schema_name, grant_select_to, self.grant_select_on_all_tables_in_schema) else: logger.info("Table '{}' exists".format(stream)) self.update_columns() From a1d45393b4f0de83a993b62ae20d8f85a6ed9fa7 Mon Sep 17 00:00:00 2001 From: Peter Kosztolanyi Date: Sun, 14 Oct 2018 00:24:59 +0100 Subject: [PATCH 2/3] Log info when new schema created --- target_postgres/db_sync.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/target_postgres/db_sync.py b/target_postgres/db_sync.py index e986309..7bd2089 100644 --- a/target_postgres/db_sync.py +++ b/target_postgres/db_sync.py @@ -282,7 +282,9 @@ def create_schema_if_not_exists(self): ) if len(schema_rows) == 0: - self.query("CREATE SCHEMA IF NOT EXISTS {}".format(schema_name)) + query = "CREATE SCHEMA IF NOT EXISTS {}".format(schema_name) + logger.info("Schema '{}' does not exist. Creating... {}".format(schema_name, query)) + self.query(query) if 'grant_select_to' in self.connection_config: grant_select_to = self.connection_config['grant_select_to'] From ce88dcfd69de56a915233f29a20a4aba356effac Mon Sep 17 00:00:00 2001 From: Peter Kosztolanyi Date: Sun, 14 Oct 2018 00:34:09 +0100 Subject: [PATCH 3/3] Updated README.md with config properties --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index da7ed91..eeeb859 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,31 @@ This is a [Singer](https://singer.io) target for Postgres following the [Singer spec](https://github.com/singer-io/getting-started/blob/master/SPEC.md). +#### Samle config: + + { + "host": "localhost", + "user": "test", + "port": "5432", + "password": "", + "dbname": "target_test", + "schema": "test_schema" + } + +#### Mandatory properties: + +`host`: The host name of the PostgreSQL server + +`user`: The database user on whose behalf the connection is being made. + +`port`: The port number the server is listening on + +`password`: The database user's password. + +`dbname`: The database name + +`schema`: Destination schema name + +#### Optional properties: + +`grant_select_to`: String or Array. When a new schema or table is created, SELECT privilege will be granted to one or more ROLEs automatically.