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

Support for roles in grants #259

Merged
merged 21 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
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
6 changes: 0 additions & 6 deletions .github/expected_failures.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,6 @@ tests/functional/adapter/dbt_clone/test_dbt_clone.py::TestCloneNotPossibleDremio
tests/functional/adapter/dremio_specific/test_drop_temp_table.py::TestDropTempTableDremio::test_drop_temp_table
tests/functional/adapter/dremio_specific/test_schema_parsing.py::TestSchemaParsingDremio::test_schema_with_dots
tests/functional/adapter/dremio_specific/test_verify_ssl.py::TestVerifyCertificateDremio::test_insecure_request_warning_not_exist
tests/functional/adapter/grants/test_incremental_grants.py::TestIncrementalGrantsDremio::test_incremental_grants
tests/functional/adapter/grants/test_invalid_grants.py::TestInvalidGrantsDremio::test_invalid_grants
tests/functional/adapter/grants/test_model_grants.py::TestViewGrantsDremio::test_view_table_grants
tests/functional/adapter/grants/test_model_grants.py::TestTableGrantsDremio::test_view_table_grants
tests/functional/adapter/grants/test_seed_grants.py::TestSeedGrantsDremio::test_seed_grants
tests/functional/adapter/grants/test_snapshot_grants.py::TestSnapshotGrantsDremio::test_snapshot_grants
tests/functional/adapter/relation/test_get_relation_last_modified.py::TestGetLastRelationModified::test_get_last_relation_modified
tests/functional/adapter/unit_testing/test_unit_testing.py::TestDremioUnitTestingTypes::test_unit_test_data_type
tests/functional/adapter/unit_testing/test_unit_testing.py::TestDremioUnitTestCaseInsensitivity::test_case_insensitivity
Expand Down
3 changes: 3 additions & 0 deletions .github/scripts/create_env_file.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ DREMIO_DATABASE=dbt_test
DBT_TEST_USER_1=dbt_test_user_1
DBT_TEST_USER_2=dbt_test_user_2
DBT_TEST_USER_3=dbt_test_user_3
DBT_TEST_ROLE_1=dbt_test_role_1
DBT_TEST_ROLE_2=dbt_test_role_2
DREMIO_EDITION=community
bcmeireles marked this conversation as resolved.
Show resolved Hide resolved
EOF

echo ".env file created successfully."
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
## Changes

- When naming reflections, if a `name` config is not set, the `alias` config parameter will be used instead. If also undefined, it will refer to the model name instead of using `Unnamed Reflection`
- Grants can now be set for both users and for roles. A prefix was added to handle this, with `user:` and `role:` being the valid prefixes. For example, `user:dbt_test_user_1` and `role:dbt_test_role_1`. If no prefix is provided, defaults to user for backwards compatibility.

## Features

- [#259](https://github.com/dremio/dbt-dremio/pull/259) Added support for roles in grants

# dbt-dremio v1.8.1

Expand Down
6 changes: 4 additions & 2 deletions dbt/adapters/dremio/impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,12 @@ def standardize_grants_dict(self, grants_table: agate.Table) -> dict:
# Just needed to change these two values to match Dremio cols
grantee = row["grantee_id"]
privilege = row["privilege"]
grantee_type = row["grantee_type"]

if privilege in grants_dict.keys():
grants_dict[privilege].append(grantee)
grants_dict[privilege].append(f"{grantee_type}:{grantee}")
else:
grants_dict.update({privilege: [grantee]})
grants_dict.update({privilege: [f"{grantee_type}:{grantee}"]})
return grants_dict

# This is for use in the test suite
Expand Down
32 changes: 28 additions & 4 deletions dbt/include/dremio/macros/adapters/apply_grants.sql
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@ limitations under the License.*/
{{ return(False) }}
{%- endmacro -%}

{%- macro dremio__split_grantee(grantee) -%}
howareyouman marked this conversation as resolved.
Show resolved Hide resolved
{%- set splitted = grantee.split(':') -%}

{%- if splitted | length < 2 -%}
{{ log("Deprecation warning: grants to users will soon require the user: prefix", info=True) }}
{{ return(("user", grantee)) }}
bcmeireles marked this conversation as resolved.
Show resolved Hide resolved
{%- else -%}
{%- set prefix = splitted[0] -%}
{%- set remainder = splitted[1:] | join(':') -%}

{%- if prefix not in ['user', 'role'] -%}
{% do exceptions.CompilationError("Invalid prefix. Use either user or role") %}
{%- endif -%}

{{ return((prefix, remainder)) }}
{%- endif -%}
{%- endmacro -%}

{% macro dremio__get_show_grant_sql(relation) %}
{%- if relation.type == 'table' -%}
{%- set relation_without_double_quotes = target.datalake ~ '.' ~ target.root_path ~ '.' ~ relation.identifier-%}
Expand All @@ -30,17 +48,23 @@ limitations under the License.*/
{%- else -%}
{% do exceptions.CompilationError("Invalid profile configuration: please only specify one of cloud_host or software_host in profiles.yml") %}
{%- endif %}
SELECT privilege, grantee_id
SELECT privilege, grantee_type, grantee_id
FROM {{privileges_table}}
WHERE object_id='{{ relation_without_double_quotes }}'
{% endmacro %}

{%- macro dremio__get_grant_sql(relation, privilege, grantees) -%}
grant {{ privilege }} on {{relation.type}} {{ relation }} to user {{adapter.quote(grantees[0])}}
{%- set type, name = dremio__split_grantee(grantees[0]) %}

grant {{ privilege }} on {{ relation.type }} {{ relation }}
to {{ type }} {{ adapter.quote(name) }}
{%- endmacro -%}

{%- macro default__get_revoke_sql(relation, privilege, grantees) -%}
revoke {{ privilege }} on {{ relation.type }} {{ relation }} from user {{adapter.quote(grantees[0])}}
{%- macro dremio__get_revoke_sql(relation, privilege, grantees) -%}
{%- set type, name = dremio__split_grantee(grantees[0]) %}

revoke {{ privilege }} on {{ relation.type }} {{ relation }}
from {{ type }} {{ adapter.quote(name) }}
{%- endmacro -%}

{% macro dremio__call_dcl_statements(dcl_statement_list) %}
Expand Down
7 changes: 5 additions & 2 deletions tests/functional/adapter/grants/test_incremental_grants.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import pytest

from dbt.tests.util import (
run_dbt_and_capture,
get_manifest,
Expand All @@ -27,6 +29,7 @@
)


@pytest.mark.skip(reason="Dremio only supports grants in EE/DC editions.")
class TestIncrementalGrantsDremio(BaseGrantsDremio, BaseIncrementalGrants):
# Define this here to use our modified version of relation_from_name
def get_grants_on_relation(self, project, relation_name):
Expand All @@ -53,7 +56,7 @@ def test_incremental_grants(self, project, get_test_users):
model_id = "model.test.my_incremental_model"
model = manifest.nodes[model_id]
assert model.config.materialized == "incremental"
expected = {select_privilege_name: [test_users[0]]}
expected = {select_privilege_name: ["user:" + test_users[0]]}
self.assert_expected_grants_match_actual(
project, "my_incremental_model", expected
)
Expand All @@ -80,7 +83,7 @@ def test_incremental_grants(self, project, get_test_users):
manifest = get_manifest(project.project_root)
model = manifest.nodes[model_id]
assert model.config.materialized == "incremental"
expected = {select_privilege_name: [test_users[1]]}
expected = {select_privilege_name: ["user:" + test_users[1]]}
self.assert_expected_grants_match_actual(
project, "my_incremental_model", expected
)
Expand Down
2 changes: 2 additions & 0 deletions tests/functional/adapter/grants/test_invalid_grants.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import pytest

from dbt.tests.adapter.grants.test_invalid_grants import BaseInvalidGrants
from tests.functional.adapter.grants.base_grants import BaseGrantsDremio
from tests.utils.util import relation_from_name
from dbt.tests.util import get_connection


@pytest.mark.skip(reason="Dremio only supports grants in EE/DC editions.")
bcmeireles marked this conversation as resolved.
Show resolved Hide resolved
class TestInvalidGrantsDremio(BaseGrantsDremio, BaseInvalidGrants):
def grantee_does_not_exist_error(self):
return "Grant on catalog entity failed. User invalid_user does not exist."
Expand Down
Loading
Loading