Skip to content

Commit 0e9c546

Browse files
authored
Support for roles in grants (dremio#259)
### Summary Added support for roles in grants ### Description 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. ### Test Results Tests were ran against a local Dremio Enterprise instance and are skipped since the current pipeline uses Dremio OSS, and grants are an Enterprise feature ### Changelog - Added support for roles in grants ### Related Issue dremio#177
1 parent d2ca686 commit 0e9c546

File tree

10 files changed

+251
-21
lines changed

10 files changed

+251
-21
lines changed

.github/expected_failures.txt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,6 @@ tests/functional/adapter/dbt_clone/test_dbt_clone.py::TestCloneNotPossibleDremio
33
tests/functional/adapter/dremio_specific/test_drop_temp_table.py::TestDropTempTableDremio::test_drop_temp_table
44
tests/functional/adapter/dremio_specific/test_schema_parsing.py::TestSchemaParsingDremio::test_schema_with_dots
55
tests/functional/adapter/dremio_specific/test_verify_ssl.py::TestVerifyCertificateDremio::test_insecure_request_warning_not_exist
6-
tests/functional/adapter/grants/test_incremental_grants.py::TestIncrementalGrantsDremio::test_incremental_grants
7-
tests/functional/adapter/grants/test_invalid_grants.py::TestInvalidGrantsDremio::test_invalid_grants
8-
tests/functional/adapter/grants/test_model_grants.py::TestViewGrantsDremio::test_view_table_grants
9-
tests/functional/adapter/grants/test_model_grants.py::TestTableGrantsDremio::test_view_table_grants
10-
tests/functional/adapter/grants/test_seed_grants.py::TestSeedGrantsDremio::test_seed_grants
11-
tests/functional/adapter/grants/test_snapshot_grants.py::TestSnapshotGrantsDremio::test_snapshot_grants
126
tests/functional/adapter/relation/test_get_relation_last_modified.py::TestGetLastRelationModified::test_get_last_relation_modified
137
tests/functional/adapter/unit_testing/test_unit_testing.py::TestDremioUnitTestingTypes::test_unit_test_data_type
148
tests/functional/adapter/unit_testing/test_unit_testing.py::TestDremioUnitTestCaseInsensitivity::test_case_insensitivity

.github/scripts/create_env_file.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ DREMIO_DATABASE=dbt_test
1616
DBT_TEST_USER_1=dbt_test_user_1
1717
DBT_TEST_USER_2=dbt_test_user_2
1818
DBT_TEST_USER_3=dbt_test_user_3
19+
DBT_TEST_ROLE_1=dbt_test_role_1
20+
DBT_TEST_ROLE_2=dbt_test_role_2
21+
DREMIO_EDITION=community
1922
EOF
2023

2124
echo ".env file created successfully."

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
## Changes
44

55
- 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`
6+
- 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.
7+
8+
## Features
9+
10+
- [#259](https://github.com/dremio/dbt-dremio/pull/259) Added support for roles in grants
611

712
# dbt-dremio v1.8.1
813

dbt/adapters/dremio/impl.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,12 @@ def standardize_grants_dict(self, grants_table: agate.Table) -> dict:
149149
# Just needed to change these two values to match Dremio cols
150150
grantee = row["grantee_id"]
151151
privilege = row["privilege"]
152+
grantee_type = row["grantee_type"]
153+
152154
if privilege in grants_dict.keys():
153-
grants_dict[privilege].append(grantee)
155+
grants_dict[privilege].append(f"{grantee_type}:{grantee}")
154156
else:
155-
grants_dict.update({privilege: [grantee]})
157+
grants_dict.update({privilege: [f"{grantee_type}:{grantee}"]})
156158
return grants_dict
157159

158160
# This is for use in the test suite

dbt/include/dremio/macros/adapters/apply_grants.sql

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,24 @@ limitations under the License.*/
1616
{{ return(False) }}
1717
{%- endmacro -%}
1818

19+
{%- macro dremio__split_grantee(grantee) -%}
20+
{%- set splitted = grantee.split(':') -%}
21+
22+
{%- if splitted | length < 2 -%}
23+
{{ log("Deprecation warning: grants to users will soon require the user: prefix", info=True) }}
24+
{{ return(("user", grantee)) }}
25+
{%- else -%}
26+
{%- set prefix = splitted[0] -%}
27+
{%- set remainder = splitted[1:] | join(':') -%}
28+
29+
{%- if prefix not in ['user', 'role'] -%}
30+
{% do exceptions.CompilationError("Invalid prefix. Use either user or role") %}
31+
{%- endif -%}
32+
33+
{{ return((prefix, remainder)) }}
34+
{%- endif -%}
35+
{%- endmacro -%}
36+
1937
{% macro dremio__get_show_grant_sql(relation) %}
2038
{%- if relation.type == 'table' -%}
2139
{%- set relation_without_double_quotes = target.datalake ~ '.' ~ target.root_path ~ '.' ~ relation.identifier-%}
@@ -30,17 +48,23 @@ limitations under the License.*/
3048
{%- else -%}
3149
{% do exceptions.CompilationError("Invalid profile configuration: please only specify one of cloud_host or software_host in profiles.yml") %}
3250
{%- endif %}
33-
SELECT privilege, grantee_id
51+
SELECT privilege, grantee_type, grantee_id
3452
FROM {{privileges_table}}
3553
WHERE object_id='{{ relation_without_double_quotes }}'
3654
{% endmacro %}
3755

3856
{%- macro dremio__get_grant_sql(relation, privilege, grantees) -%}
39-
grant {{ privilege }} on {{relation.type}} {{ relation }} to user {{adapter.quote(grantees[0])}}
57+
{%- set type, name = dremio__split_grantee(grantees[0]) %}
58+
59+
grant {{ privilege }} on {{ relation.type }} {{ relation }}
60+
to {{ type }} {{ adapter.quote(name) }}
4061
{%- endmacro -%}
4162

42-
{%- macro default__get_revoke_sql(relation, privilege, grantees) -%}
43-
revoke {{ privilege }} on {{ relation.type }} {{ relation }} from user {{adapter.quote(grantees[0])}}
63+
{%- macro dremio__get_revoke_sql(relation, privilege, grantees) -%}
64+
{%- set type, name = dremio__split_grantee(grantees[0]) %}
65+
66+
revoke {{ privilege }} on {{ relation.type }} {{ relation }}
67+
from {{ type }} {{ adapter.quote(name) }}
4468
{%- endmacro -%}
4569

4670
{% macro dremio__call_dcl_statements(dcl_statement_list) %}

tests/functional/adapter/grants/test_incremental_grants.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import pytest, os
16+
1517
from dbt.tests.util import (
1618
run_dbt_and_capture,
1719
get_manifest,
@@ -26,7 +28,9 @@
2628
user2_incremental_model_schema_yml,
2729
)
2830

31+
DREMIO_EDITION = os.getenv("DREMIO_EDITION")
2932

33+
@pytest.mark.skipif(DREMIO_EDITION == "community", reason="Dremio only supports grants in EE/DC editions.")
3034
class TestIncrementalGrantsDremio(BaseGrantsDremio, BaseIncrementalGrants):
3135
# Define this here to use our modified version of relation_from_name
3236
def get_grants_on_relation(self, project, relation_name):
@@ -53,7 +57,7 @@ def test_incremental_grants(self, project, get_test_users):
5357
model_id = "model.test.my_incremental_model"
5458
model = manifest.nodes[model_id]
5559
assert model.config.materialized == "incremental"
56-
expected = {select_privilege_name: [test_users[0]]}
60+
expected = {select_privilege_name: ["user:" + test_users[0]]}
5761
self.assert_expected_grants_match_actual(
5862
project, "my_incremental_model", expected
5963
)
@@ -80,7 +84,7 @@ def test_incremental_grants(self, project, get_test_users):
8084
manifest = get_manifest(project.project_root)
8185
model = manifest.nodes[model_id]
8286
assert model.config.materialized == "incremental"
83-
expected = {select_privilege_name: [test_users[1]]}
87+
expected = {select_privilege_name: ["user:" + test_users[1]]}
8488
self.assert_expected_grants_match_actual(
8589
project, "my_incremental_model", expected
8690
)

tests/functional/adapter/grants/test_invalid_grants.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import pytest, os
1516

1617
from dbt.tests.adapter.grants.test_invalid_grants import BaseInvalidGrants
1718
from tests.functional.adapter.grants.base_grants import BaseGrantsDremio
1819
from tests.utils.util import relation_from_name
1920
from dbt.tests.util import get_connection
2021

22+
DREMIO_EDITION = os.getenv("DREMIO_EDITION")
2123

24+
@pytest.mark.skipif(DREMIO_EDITION == "community", reason="Dremio only supports grants in EE/DC editions.")
2225
class TestInvalidGrantsDremio(BaseGrantsDremio, BaseInvalidGrants):
2326
def grantee_does_not_exist_error(self):
2427
return "Grant on catalog entity failed. User invalid_user does not exist."

0 commit comments

Comments
 (0)