Skip to content

Commit 68132f9

Browse files
saraivdbxSara Ivanyos
andauthored
Validate toolkit notebook test (#183)
Toolkit notebook test validated. Switched order of crawling TACL and group migration in notebook toolkit.py. --------- Co-authored-by: Sara Ivanyos <[email protected]>
1 parent 688002c commit 68132f9

File tree

3 files changed

+131
-47
lines changed

3 files changed

+131
-47
lines changed

notebooks/toolkit.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,16 @@
9494

9595
# COMMAND ----------
9696

97+
# MAGIC %md
98+
# MAGIC
99+
# MAGIC ## Inventorize Table ACL's
100+
101+
# COMMAND ----------
102+
103+
tacltoolkit.grants_snapshot()
104+
105+
# COMMAND ----------
106+
97107
# MAGIC %md
98108
# MAGIC
99109
# MAGIC ## Inventorize the permissions
@@ -148,15 +158,6 @@
148158

149159
toolkit.delete_backup_groups()
150160

151-
# COMMAND ----------
152-
153-
# MAGIC %md
154-
# MAGIC
155-
# MAGIC ## Inventorize Table ACL's
156-
157-
# COMMAND ----------
158-
159-
tacltoolkit.grants_snapshot()
160161

161162
# COMMAND ----------
162163

src/databricks/labs/ucx/toolkits/group_migration.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
from databricks.labs.ucx.config import MigrationConfig
66
from databricks.labs.ucx.inventory.inventorizer import Inventorizers
77
from databricks.labs.ucx.inventory.permissions import PermissionManager
8-
from databricks.labs.ucx.inventory.permissions_inventory import PermissionsInventoryTable
8+
from databricks.labs.ucx.inventory.permissions_inventory import (
9+
PermissionsInventoryTable,
10+
)
911
from databricks.labs.ucx.managers.group import GroupManager
1012

1113

tests/integration/test_installation.py

Lines changed: 118 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
import os
3+
import random
34
import shutil
45
import subprocess
56
import sys
@@ -8,9 +9,13 @@
89

910
import pytest
1011
from databricks.sdk.service import compute, jobs
12+
from databricks.sdk.service.iam import PermissionLevel
1113
from databricks.sdk.service.workspace import ImportFormat
1214

15+
from databricks.labs.ucx.inventory.types import RequestObjectType
1316
from databricks.labs.ucx.providers.mixins.compute import CommandExecutor
17+
from databricks.labs.ucx.tacl.grants import Grant
18+
from databricks.labs.ucx.tacl.tables import Table
1419

1520
logger = logging.getLogger(__name__)
1621

@@ -96,63 +101,55 @@ def test_sql_backend_works(ws, wsfs_wheel):
96101
def test_toolkit_notebook(
97102
ws,
98103
sql_exec,
104+
sql_fetch_all,
99105
wsfs_wheel,
100-
make_cluster,
101106
make_cluster_policy,
102-
make_directory,
107+
make_cluster_policy_permissions,
103108
make_ucx_group,
104-
make_instance_pool,
105109
make_job,
106-
make_notebook,
107-
make_pipeline,
110+
make_job_permissions,
108111
make_random,
109-
make_repo,
110-
make_secret_scope,
111112
make_schema,
112113
make_table,
113-
make_user,
114114
):
115115
logger.info("setting up fixtures")
116116

117-
user_a = make_user()
118-
user_b = make_user()
119-
user_c = make_user()
120-
121-
logger.info(f"user_a={user_a}, user_b={user_b}, user_c={user_c}, ")
122-
123-
# TODO add users to groups
124117
ws_group_a, acc_group_a = make_ucx_group()
118+
members_src_a = sorted([_.display for _ in ws.groups.get(id=ws_group_a.id).members])
125119
ws_group_b, acc_group_b = make_ucx_group()
120+
members_src_b = sorted([_.display for _ in ws.groups.get(id=ws_group_b.id).members])
126121
ws_group_c, acc_group_c = make_ucx_group()
122+
members_src_c = sorted([_.display for _ in ws.groups.get(id=ws_group_c.id).members])
127123

128124
selected_groups = ",".join([ws_group_a.display_name, ws_group_b.display_name, ws_group_c.display_name])
129125

130126
logger.info(f"group_a={ws_group_a}, group_b={ws_group_b}, group_c={ws_group_c}, ")
131127

132-
cluster = make_cluster(instance_pool_id=os.environ["TEST_INSTANCE_POOL_ID"], single_node=True)
133128
cluster_policy = make_cluster_policy()
134-
directory = make_directory()
135-
instance_pool = make_instance_pool()
129+
make_cluster_policy_permissions(
130+
object_id=cluster_policy.policy_id,
131+
permission_level=random.choice([PermissionLevel.CAN_USE]),
132+
group_name=ws_group_a.display_name,
133+
)
134+
cpp_src = ws.permissions.get(RequestObjectType.CLUSTER_POLICIES, cluster_policy.policy_id)
135+
cluster_policy_src_permissions = sorted(
136+
[_ for _ in cpp_src.access_control_list if _.group_name == ws_group_a.display_name],
137+
key=lambda p: p.group_name,
138+
)
136139
job = make_job()
137-
notebook = make_notebook()
138-
pipeline = make_pipeline()
139-
repo = make_repo()
140-
secret_scope = make_secret_scope()
141-
142-
logger.info(
143-
f"cluster={cluster}, "
144-
f"cluster_policy={cluster_policy}, "
145-
f"directory={directory}, "
146-
f"instance_pool={instance_pool}, "
147-
f"job={job}, "
148-
f"notebook={notebook}, "
149-
f"pipeline={pipeline}"
150-
f"repo={repo}, "
151-
f"secret_scope={secret_scope}, "
140+
make_job_permissions(
141+
object_id=job.job_id,
142+
permission_level=random.choice(
143+
[PermissionLevel.CAN_VIEW, PermissionLevel.CAN_MANAGE_RUN, PermissionLevel.CAN_MANAGE]
144+
),
145+
group_name=ws_group_b.display_name,
152146
)
153-
154-
# TODO create fixtures for DBSQL assets
155-
# TODO set permissions
147+
jp_src = ws.permissions.get(RequestObjectType.JOBS, job.job_id)
148+
job_src_permissions = sorted(
149+
[_ for _ in jp_src.access_control_list if _.group_name == ws_group_b.display_name],
150+
key=lambda p: p.group_name,
151+
)
152+
logger.info(f"cluster_policy={cluster_policy}, job={job}, ")
156153

157154
schema_a = make_schema()
158155
schema_b = make_schema()
@@ -222,7 +219,91 @@ def test_toolkit_notebook(
222219

223220
try:
224221
ws.jobs.run_now(created_job.job_id).result()
225-
# TODO Validate migration, tacl
222+
223+
logger.info("validating group ids")
224+
225+
dst_ws_group_a = ws.groups.list(filter=f"displayName eq {ws_group_a.display_name}")[0]
226+
assert (
227+
ws_group_a.id != dst_ws_group_a.id
228+
), f"Group id for target group {ws_group_a.display_name} should differ from group id of source group"
229+
230+
dst_ws_group_b = ws.groups.list(filter=f"displayName eq {ws_group_b.display_name}")[0]
231+
assert (
232+
ws_group_b.id != dst_ws_group_b.id
233+
), f"Group id for target group {ws_group_b.display_name} should differ from group id of source group"
234+
235+
dst_ws_group_c = ws.groups.list(filter=f"displayName eq {ws_group_c.display_name}")[0]
236+
assert (
237+
ws_group_c.id != dst_ws_group_c.id
238+
), f"Group id for target group {ws_group_c.display_name} should differ from group id of source group"
239+
240+
logger.info("validating group members")
241+
242+
members_dst_a = sorted([_.display for _ in ws.groups.get(id=dst_ws_group_a.id).members])
243+
assert members_dst_a == members_src_a, f"Members from {ws_group_a.display_name} were not migrated correctly"
244+
245+
members_dst_b = sorted([_.display for _ in ws.groups.get(id=dst_ws_group_b.id).members])
246+
assert members_dst_b == members_src_b, f"Members in {ws_group_b.display_name} were not migrated correctly"
247+
248+
members_dst_c = sorted([_.display for _ in ws.groups.get(id=dst_ws_group_c.id).members])
249+
assert members_dst_c == members_src_c, f"Members in {ws_group_c.display_name} were not migrated correctly"
250+
251+
logger.info("validating permissions")
252+
253+
cp_dst = ws.permissions.get(RequestObjectType.CLUSTER_POLICIES, cluster_policy.policy_id)
254+
cluster_policy_dst_permissions = sorted(
255+
[_ for _ in cp_dst.access_control_list if _.group_name == ws_group_a.display_name],
256+
key=lambda p: p.group_name,
257+
)
258+
assert len(cluster_policy_dst_permissions) == len(
259+
cluster_policy_src_permissions
260+
), "Target permissions were not applied correctly for cluster policies"
261+
assert [t.all_permissions for t in cluster_policy_dst_permissions] == [
262+
s.all_permissions for s in cluster_policy_src_permissions
263+
], "Target permissions were not applied correctly for cluster policies"
264+
265+
jp_dst = ws.permissions.get(RequestObjectType.JOBS, job.job_id)
266+
job_dst_permissions = sorted(
267+
[_ for _ in jp_dst.access_control_list if _.group_name == ws_group_b.display_name],
268+
key=lambda p: p.group_name,
269+
)
270+
assert len(job_dst_permissions) == len(
271+
job_src_permissions
272+
), f"Target permissions were not applied correctly for {RequestObjectType.JOBS}/{job.job_id}"
273+
assert [t.all_permissions for t in job_dst_permissions] == [
274+
s.all_permissions for s in job_src_permissions
275+
], f"Target permissions were not applied correctly for {RequestObjectType.JOBS}/{job.job_id}"
276+
277+
logger.info("validating tacl")
278+
279+
tables = sql_fetch_all(f"SELECT * FROM hive_metastore.{inventory_database}.tables")
280+
print(list(sql_fetch_all(f"SELECT * FROM hive_metastore.{inventory_database}.tables")))
281+
282+
all_tables = {}
283+
for t_row in tables:
284+
table = Table(*t_row)
285+
all_tables[table.key] = table
286+
287+
assert len(all_tables) >= 2, "must have at least two tables"
288+
289+
logger.debug(f"all tables={all_tables}, ")
290+
291+
grants = sql_fetch_all(f"SELECT * FROM hive_metastore.{inventory_database}.grants")
292+
all_grants = {}
293+
for g_row in grants:
294+
grant = Grant(*g_row)
295+
if grant.table:
296+
all_grants[f"{grant.principal}.{grant.catalog}.{grant.database}.{grant.table}"] = grant.action_type
297+
else:
298+
all_grants[f"{grant.principal}.{grant.catalog}.{grant.database}"] = grant.action_type
299+
300+
logger.debug(f"all grants={all_grants}, ")
301+
302+
assert len(all_grants) >= 3, "must have at least three grants"
303+
assert all_grants[f"{ws_group_a.display_name}.{table_a}"] == "SELECT"
304+
assert all_grants[f"{ws_group_b.display_name}.{table_b}"] == "SELECT"
305+
assert all_grants[f"{ws_group_b.display_name}.{schema_b}"] == "MODIFY"
306+
226307
finally:
227308
logger.info("deleting workbook")
228309

0 commit comments

Comments
 (0)