Skip to content
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

Add Grants to BigQuery Materializations #212

Merged
merged 31 commits into from
Jul 11, 2022
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
712d22b
Add get_show_grant_sql
emmyoop Jun 27, 2022
5bb3afd
first pass at granting with sql
emmyoop Jun 27, 2022
aeb19f3
more macro overrides
emmyoop Jun 29, 2022
911fed0
Merge branch 'main' of https://github.com/dbt-labs/dbt-bigquery into …
emmyoop Jul 7, 2022
42ae831
update macros, temp update to dev-req for CI
emmyoop Jul 7, 2022
a661549
tweak to sql and added some TODOs
emmyoop Jul 7, 2022
b0b06ef
move things around
emmyoop Jul 7, 2022
e0909ca
exclude session_user
emmyoop Jul 7, 2022
9f73a3a
Merge branch 'main' of https://github.com/dbt-labs/dbt-bigquery into …
emmyoop Jul 7, 2022
0733a5f
fix mypy error, fix exclude to be more than users
emmyoop Jul 7, 2022
ce094b7
simplify revoke logic
emmyoop Jul 7, 2022
83c73e0
small cleanup, point to ct-660 branch
emmyoop Jul 8, 2022
0cdeb1e
grant entire list in one statement
emmyoop Jul 8, 2022
8070891
wip
emmyoop Jul 8, 2022
d8f6e2d
wip, broken tests
emmyoop Jul 8, 2022
10cc952
Update dbt/include/bigquery/macros/materializations/incremental.sql
emmyoop Jul 8, 2022
cb42c81
working on getting tests working, very WIP
emmyoop Jul 8, 2022
2dde9ee
Merge branch 'main' of https://github.com/dbt-labs/dbt-bigquery into …
emmyoop Jul 8, 2022
9f51fab
Merge branch 'er/ct-717-grant-materialization' of https://github.com/…
emmyoop Jul 8, 2022
118d311
All tests passing locally
jtcohen6 Jul 10, 2022
2957696
Updated user / group names
dbeatty10 Jul 11, 2022
f61bd39
Ongoing test cleanup
jtcohen6 Jul 11, 2022
210830d
Merge branch 'dbeatty/grantee-env-vars-take-2' into er/ct-717-grant-m…
jtcohen6 Jul 11, 2022
c4ce8d6
Account for refactor in dbt-labs/dbt-core@c763601
jtcohen6 Jul 11, 2022
cee9fa1
Updated third value
dbeatty10 Jul 11, 2022
d6aedf8
Merge branch 'dbeatty/grantee-env-vars-take-2' into er/ct-717-grant-m…
dbeatty10 Jul 11, 2022
27c41ed
Alt approach for grant location (#218)
jtcohen6 Jul 11, 2022
3b9c9a4
Merge branch 'main' of https://github.com/dbt-labs/dbt-bigquery into …
emmyoop Jul 11, 2022
a6ef920
reset to point dbt-core to main instead of branch
emmyoop Jul 11, 2022
f47322f
fix examples in test.env.example
emmyoop Jul 11, 2022
d94b623
add changelog
emmyoop Jul 11, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions dbt/adapters/bigquery/impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,29 @@ def list_relations_without_caching(
logger.debug("list_relations_without_caching error: {}".format(str(exc)))
return []

@available
def standardize_grants_dict(self, grants_table: agate.Table) -> dict:
emmyoop marked this conversation as resolved.
Show resolved Hide resolved
"""Translate the result of `show grants` (or equivalent) to match the
grants which a user would configure in their project.

If relevant -- filter down to grants made BY the current user role,
and filter OUT any grants TO the current user/role (e.g. OWNERSHIP).

:param grants_table: An agate table containing the query result of
the SQL returned by get_show_grant_sql
:return: A standardized dictionary matching the `grants` config
:rtype: dict
"""
grants_dict: Dict[str, List] = {}
for row in grants_table:
grantee = row["grantee"]
privilege = row["privilege_type"]
if privilege in grants_dict.keys():
grants_dict[privilege].append(grantee)
else:
grants_dict.update({privilege: [grantee]})
return grants_dict

def get_relation(self, database: str, schema: str, identifier: str) -> BigQueryRelation:
if self._schema_is_cached(database, schema):
# if it's in the cache, use the parent's model of going through
Expand Down
28 changes: 28 additions & 0 deletions dbt/include/bigquery/macros/adapters/apply_grants.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{% macro bigquery__get_show_grant_sql(relation) %}
{% if not target.location %}
{{ exceptions.raise_compiler_error("In order to use the grants feature, you must specify a location ") }}
{% endif %}

select privilege_type, grantee from {{ relation.project }}.`region-{{ target.location }}`.INFORMATION_SCHEMA.OBJECT_PRIVILEGES
emmyoop marked this conversation as resolved.
Show resolved Hide resolved
emmyoop marked this conversation as resolved.
Show resolved Hide resolved
where object_schema = "{{ relation.dataset }}" and object_name = "{{ relation.identifier }}" and split(grantee, ':')[offset(1)] != session_user()
{% endmacro %}


{%- macro bigquery__get_grant_sql(relation, grant_config) -%}
{%- for privilege in grant_config.keys() -%}
{%- set grantees = grant_config[privilege] -%}
{%- if grantees -%}
grant `{{ privilege }}` on {{ relation.type }} {{ relation }} to {{ '\"' + grantees|join('\", \"') + '\"' }};
{% endif -%}
{%- endfor -%}
{%- endmacro %}


{% macro bigquery__get_revoke_sql(relation, grant_config) %}
{%- for privilege in grant_config.keys() -%}
{%- set grantees = grant_config[privilege] -%}
{%- if grantees -%}
revoke `{{ privilege }}` on {{ relation.type }} {{ relation }} from {{ '\"' + grantees|join('\", \"') + '\"' }};
{% endif -%}
{%- endfor -%}
{%- endmacro -%}
3 changes: 2 additions & 1 deletion dbt/include/bigquery/macros/materializations/copy.sql
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
{{ source_array.append(source(*src_table)) }}
{% endfor %}

{# Call adapter's copy_table function #}
{# Call adapter copy_table function #}
{%- set result_str = adapter.copy_table(
source_array,
destination,
Expand All @@ -26,6 +26,7 @@

{# Clean up #}
{{ run_hooks(post_hooks) }}
{%- do apply_grants(target_relation, grant_config) -%}
{{ adapter.commit() }}

{{ return({'relations': [destination]}) }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
{%- set tmp_relation = make_temp_relation(this) %}

{#-- Validate early so we don't run SQL if the strategy is invalid --#}
{% set strategy = dbt_bigquery_validate_get_incremental_strategy(config) -%}
{%- set strategy = dbt_bigquery_validate_get_incremental_strategy(config) -%}
emmyoop marked this conversation as resolved.
Show resolved Hide resolved

{%- set raw_partition_by = config.get('partition_by', none) -%}
{%- set partition_by = adapter.parse_partition_by(raw_partition_by) -%}
Expand All @@ -152,6 +152,9 @@

{% set on_schema_change = incremental_validate_on_schema_change(config.get('on_schema_change'), default='ignore') %}

-- grab current tables grants config for comparision later on
{% set grant_config = config.get('grants') %}

{{ run_hooks(pre_hooks) }}

{% if existing_relation is none %}
Expand Down Expand Up @@ -197,6 +200,8 @@

{% set target_relation = this.incorporate(type='table') %}

{% do apply_grants(target_relation, grant_config) %}

{% do persist_docs(target_relation, model) %}

{{ return({'relations': [target_relation]}) }}
Expand Down
5 changes: 5 additions & 0 deletions dbt/include/bigquery/macros/materializations/table.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
{%- set exists_not_as_table = (old_relation is not none and not old_relation.is_table) -%}
{%- set target_relation = api.Relation.create(database=database, schema=schema, identifier=identifier, type='table') -%}

-- grab current tables grants config for comparision later on
{%- set grant_config = config.get('grants') -%}

{{ run_hooks(pre_hooks) }}

{#
Expand All @@ -30,6 +33,8 @@

{{ run_hooks(post_hooks) }}

{%- do apply_grants(target_relation, grant_config) -%}
emmyoop marked this conversation as resolved.
Show resolved Hide resolved

{% do persist_docs(target_relation, model) %}

{{ return({'relations': [target_relation]}) }}
Expand Down
4 changes: 4 additions & 0 deletions dbt/include/bigquery/macros/materializations/view.sql
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@


{% materialization view, adapter='bigquery' -%}
-- grab current tables grants config for comparision later on
{% set grant_config = config.get('grants') %}

{% set to_return = create_or_replace_view() %}

{% set target_relation = this.incorporate(type='view') %}
{% do apply_grants(target_relation, grant_config) %}
emmyoop marked this conversation as resolved.
Show resolved Hide resolved
{% do persist_docs(target_relation, model) %}

{% if config.get('grant_access_to') %}
Expand Down
9 changes: 7 additions & 2 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
# install latest changes in dbt-core
# TODO: how to automate switching from develop to version branches?
git+https://github.com/dbt-labs/dbt-core.git#egg=dbt-core&subdirectory=core
git+https://github.com/dbt-labs/dbt-core.git#egg=dbt-tests-adapter&subdirectory=tests/adapter

git+https://github.com/dbt-labs/dbt-core.git@ct-660-grant-sql#egg=dbt-core&subdirectory=core
git+https://github.com/dbt-labs/dbt-core.git@ct-660-grant-sql#egg=dbt-tests-adapter&subdirectory=tests/adapter

# TODO: replace above with this after dbt-core/#5263 gets merged to main
# git+https://github.com/dbt-labs/dbt-core.git#egg=dbt-core&subdirectory=core
# git+https://github.com/dbt-labs/dbt-core.git#egg=dbt-tests-adapter&subdirectory=tests/adapter
emmyoop marked this conversation as resolved.
Show resolved Hide resolved

black==22.6.0
bumpversion
Expand Down