Skip to content

Commit 2400d51

Browse files
authored
Convert READ_METADATA to UC BROWSE permission for tables, views and database (#3403)
<!-- REMOVE IRRELEVANT COMMENTS BEFORE CREATING A PULL REQUEST --> ## Changes adds logic to convert READ_METADATA in hms grants to UC BROWSE <!-- Summary of your changes that are easy to understand. Add screenshots when necessary --> Resolves #2023 ### Functionality - [ ] modified existing workflow: `...` ### Tests <!-- How is this tested? Please see the checklist below and also describe any other relevant tests --> - [ ] manually tested - [ ] added unit tests - [ ] added integration tests
1 parent 0fcbce2 commit 2400d51

File tree

4 files changed

+24
-10
lines changed

4 files changed

+24
-10
lines changed

src/databricks/labs/ucx/hive_metastore/grants.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,14 +189,17 @@ def uc_grant_sql(self, object_type: str | None = None, object_key: str | None =
189189
("FUNCTION", "SELECT"): self._uc_action("EXECUTE"),
190190
("TABLE", "SELECT"): self._uc_action("SELECT"),
191191
("TABLE", "MODIFY"): self._uc_action("MODIFY"),
192+
("TABLE", "READ_METADATA"): self._uc_action("BROWSE"),
192193
("TABLE", "ALL PRIVILEGES"): self._uc_action("ALL PRIVILEGES"),
193194
("TABLE", "OWN"): self._set_owner_sql,
194195
("VIEW", "SELECT"): self._uc_action("SELECT"),
196+
("VIEW", "READ_METADATA"): self._uc_action("BROWSE"),
195197
("VIEW", "OWN"): self._set_owner_sql,
196198
("DATABASE", "USAGE"): self._uc_action("USE SCHEMA"),
197199
("DATABASE", "CREATE"): self._uc_action("CREATE TABLE"),
198200
("DATABASE", "CREATE_NAMED_FUNCTION"): self._uc_action("CREATE FUNCTION"),
199201
("DATABASE", "SELECT"): self._uc_action("SELECT"),
202+
("DATABASE", "READ_METADATA"): self._uc_action("BROWSE"),
200203
("DATABASE", "MODIFY"): self._uc_action("MODIFY"),
201204
("DATABASE", "OWN"): self._set_owner_sql,
202205
("CATALOG", "OWN"): self._set_owner_sql,

tests/integration/hive_metastore/test_grants.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,34 +27,41 @@ def test_all_grants_in_databases(runtime_ctx, sql_backend, make_group):
2727
empty_schema = runtime_ctx.make_schema()
2828
table_a = runtime_ctx.make_table(schema_name=schema_a.name)
2929
table_b = runtime_ctx.make_table(schema_name=schema_b.name)
30+
table_c = runtime_ctx.make_table(schema_name=schema_c.name)
3031
view_c = runtime_ctx.make_table(schema_name=schema_a.name, view=True, ctas="SELECT id FROM range(10)")
3132
view_d = runtime_ctx.make_table(schema_name=schema_a.name, view=True, ctas="SELECT id FROM range(10)")
33+
view_e = runtime_ctx.make_table(schema_name=schema_c.name, view=True, ctas="SELECT id FROM range(10)")
3234
table_e = runtime_ctx.make_table(schema_name=schema_c.name)
3335

3436
sql_backend.execute(f"GRANT USAGE ON SCHEMA {schema_c.name} TO `{group_a.display_name}`")
3537
sql_backend.execute(f"GRANT USAGE ON SCHEMA {schema_c.name} TO `{group_b.display_name}`")
3638
sql_backend.execute(f"GRANT MODIFY ON TABLE {table_e.full_name} TO `{group_b.display_name}`")
3739
sql_backend.execute(f"GRANT SELECT ON TABLE {table_a.full_name} TO `{group_a.display_name}`")
3840
sql_backend.execute(f"GRANT SELECT ON TABLE {table_b.full_name} TO `{group_b.display_name}`")
41+
sql_backend.execute(f"GRANT READ_METADATA ON TABLE {table_c.full_name} TO `{group_b.display_name}`")
3942
sql_backend.execute(f"GRANT MODIFY ON SCHEMA {schema_b.full_name} TO `{group_b.display_name}`")
40-
sql_backend.execute(f"GRANT MODIFY ON SCHEMA {empty_schema.full_name} TO `{group_b.display_name}`")
43+
sql_backend.execute(f"GRANT READ_METADATA ON SCHEMA {empty_schema.full_name} TO `{group_b.display_name}`")
4144
sql_backend.execute(f"GRANT MODIFY ON VIEW {view_c.full_name} TO `{group_b.display_name}`")
45+
sql_backend.execute(f"GRANT READ_METADATA ON VIEW {view_e.full_name} TO `{group_b.display_name}`")
4246
sql_backend.execute(f"DENY MODIFY ON TABLE {view_d.full_name} TO `{group_b.display_name}`")
4347

4448
all_grants = {}
4549
for grant in list(runtime_ctx.grants_crawler.snapshot()):
4650
logging.info(f"grant:\n{grant}\n hive: {grant.hive_grant_sql()}\n uc: {grant.uc_grant_sql()}")
47-
object_type, object_key = grant.this_type_and_key()
48-
all_grants[f"{grant.principal}.{object_type}.{object_key}"] = grant.action_type
51+
all_grants[f"{grant.principal}.{grant.this_type_and_key()[0]}.{grant.this_type_and_key()[1]}"] = (
52+
grant.action_type
53+
)
4954

50-
assert len(all_grants) >= 9, "must have at least nine grants"
55+
assert len(all_grants) >= 12, "must have at least twelve grants"
5156
assert all_grants[f"{group_a.display_name}.DATABASE.hive_metastore.{schema_c.name}"] == "USAGE"
5257
assert all_grants[f"{group_b.display_name}.DATABASE.hive_metastore.{schema_c.name}"] == "USAGE"
5358
assert all_grants[f"{group_a.display_name}.TABLE.{table_a.full_name}"] == "SELECT"
5459
assert all_grants[f"{group_b.display_name}.TABLE.{table_b.full_name}"] == "SELECT"
60+
assert all_grants[f"{group_b.display_name}.TABLE.{table_c.full_name}"] == "READ_METADATA"
5561
assert all_grants[f"{group_b.display_name}.DATABASE.{schema_b.full_name}"] == "MODIFY"
56-
assert all_grants[f"{group_b.display_name}.DATABASE.{empty_schema.full_name}"] == "MODIFY"
62+
assert all_grants[f"{group_b.display_name}.DATABASE.{empty_schema.full_name}"] == "READ_METADATA"
5763
assert all_grants[f"{group_b.display_name}.VIEW.{view_c.full_name}"] == "MODIFY"
64+
assert all_grants[f"{group_b.display_name}.VIEW.{view_e.full_name}"] == "READ_METADATA"
5865
assert all_grants[f"{group_b.display_name}.VIEW.{view_d.full_name}"] == "DENIED_MODIFY"
5966
assert all_grants[f"{group_b.display_name}.TABLE.{table_e.full_name}"] == "MODIFY"
6067

tests/unit/hive_metastore/test_grants.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def test_hive_deny_sql() -> None:
129129
[
130130
(
131131
Grant("user", "READ_METADATA", catalog="hive_metastore", database="mydb", table="mytable"),
132-
None,
132+
"GRANT BROWSE ON TABLE `hive_metastore`.`mydb`.`mytable` TO `user`",
133133
),
134134
(
135135
Grant("me", "OWN", catalog="hive_metastore", database="mydb", table="mytable"),
@@ -139,6 +139,10 @@ def test_hive_deny_sql() -> None:
139139
Grant("me", "USAGE", catalog="hive_metastore", database="mydb"),
140140
"GRANT USE SCHEMA ON DATABASE `hive_metastore`.`mydb` TO `me`",
141141
),
142+
(
143+
Grant("me", "READ_METADATA", catalog="hive_metastore", database="mydb"),
144+
"GRANT BROWSE ON DATABASE `hive_metastore`.`mydb` TO `me`",
145+
),
142146
(
143147
Grant("me", "INVALID", catalog="hive_metastore", database="mydb"),
144148
None,
@@ -718,7 +722,7 @@ def grant_loader() -> list[Grant]:
718722
return [
719723
Grant(
720724
principal="user",
721-
action_type="READ_METADATA",
725+
action_type="EXECUTE",
722726
catalog=table.catalog,
723727
database=table.database,
724728
table=table.name,
@@ -737,7 +741,7 @@ def no_owner() -> list[Grant]:
737741
with caplog.at_level(logging.WARNING, logger="databricks.labs.ucx.hive_metastore.grants"):
738742
migrate_grants.apply(table, dataclasses.replace(table, catalog="catalog"))
739743
assert (
740-
"failed-to-migrate: Hive metastore grant 'READ_METADATA' cannot be mapped to UC grant for TABLE 'catalog.database.table'"
744+
"failed-to-migrate: Hive metastore grant 'EXECUTE' cannot be mapped to UC grant for TABLE 'catalog.database.table'"
741745
in caplog.text
742746
)
743747
group_manager.assert_not_called()

tests/unit/progress/test_grants.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ def test_grant_progress_encoder_no_failures(mock_backend, grant: Grant) -> None:
4444
"Action 'DENY' on DATABASE 'hive_metastore.schema' unmappable to Unity Catalog",
4545
),
4646
(
47-
Grant("principal", "READ_METADATA", "hive_metastore", "schema", "table"),
48-
"Action 'READ_METADATA' on TABLE 'hive_metastore.schema.table' unmappable to Unity Catalog",
47+
Grant("principal", "READ_METADATA", "hive_metastore", "schema", udf="function"),
48+
"Action 'READ_METADATA' on FUNCTION 'hive_metastore.schema.function' unmappable to Unity Catalog",
4949
),
5050
],
5151
)

0 commit comments

Comments
 (0)