|
| 1 | +import datetime as dt |
1 | 2 | from dataclasses import replace |
2 | 3 |
|
3 | | - |
| 4 | +import pytest |
| 5 | +from databricks.sdk.retries import retried |
4 | 6 | from databricks.sdk.service import sql |
5 | 7 | from databricks.sdk.service.iam import PermissionLevel |
6 | 8 | from databricks.sdk.service.workspace import AclPermission |
7 | 9 |
|
8 | | -from databricks.labs.ucx.workspace_access.groups import MigratedGroup |
9 | | - |
10 | 10 |
|
11 | 11 | def test_running_real_migrate_groups_job( |
12 | 12 | installation_ctx, |
13 | 13 | make_cluster_policy, |
14 | 14 | make_cluster_policy_permissions, |
15 | 15 | make_secret_scope, |
16 | 16 | make_secret_scope_acl, |
17 | | -): |
18 | | - ws_group_a, acc_group_a = installation_ctx.make_ucx_group(wait_for_provisioning=True) |
19 | | - |
| 17 | +) -> None: |
| 18 | + """Test the migrate groups workflow. |
| 19 | +
|
| 20 | + We have many asserts in a single integration tests as we minimize the number of integration tests that run workflows |
| 21 | + to minimize the number of long-running integration tests. |
| 22 | +
|
| 23 | + For testing, we require: |
| 24 | + - UCX installation (as always) |
| 25 | + - A workspace group as the source for migration |
| 26 | + - A account group as the target for migration |
| 27 | + - Permissions to migrate: |
| 28 | + - Cluster policy |
| 29 | + - Schema and table access permissions |
| 30 | + - Secret scope permissions |
| 31 | + - Inventory tables used by the migrate groups workflow |
| 32 | +
|
| 33 | + We test: |
| 34 | + - The workflow to complete successfully |
| 35 | + - The workspace group to be renamed |
| 36 | + - The permissions to be transferred to the account group |
| 37 | + """ |
| 38 | + ws_group, acc_group = installation_ctx.make_ucx_group(wait_for_provisioning=True) |
| 39 | + |
| 40 | + # TODO: Move `make_cluster_policy` and `make_cluster_policy_permissions` to context like other `make_` methods |
20 | 41 | cluster_policy = make_cluster_policy() |
21 | 42 | make_cluster_policy_permissions( |
22 | 43 | object_id=cluster_policy.policy_id, |
23 | 44 | permission_level=PermissionLevel.CAN_USE, |
24 | | - group_name=ws_group_a.display_name, |
| 45 | + group_name=ws_group.display_name, |
25 | 46 | ) |
26 | 47 |
|
27 | | - table = installation_ctx.make_table() |
28 | | - installation_ctx.make_grant(ws_group_a.display_name, "SELECT", table_info=table) |
| 48 | + schema = installation_ctx.make_schema() |
| 49 | + table = installation_ctx.make_table(schema_name=schema.name) |
| 50 | + installation_ctx.make_grant(ws_group.display_name, 'USAGE', schema_info=schema) |
| 51 | + installation_ctx.make_grant(ws_group.display_name, 'OWN', schema_info=schema) |
| 52 | + installation_ctx.make_grant(ws_group.display_name, 'SELECT', table_info=table) |
29 | 53 |
|
| 54 | + # TODO: Move `make_secret_scope` and `make_secret_scope_acl` to context like other `make_` methods |
30 | 55 | secret_scope = make_secret_scope() |
31 | | - make_secret_scope_acl(scope=secret_scope, principal=ws_group_a.display_name, permission=AclPermission.WRITE) |
| 56 | + make_secret_scope_acl(scope=secret_scope, principal=ws_group.display_name, permission=AclPermission.WRITE) |
32 | 57 |
|
33 | | - installation_ctx.__dict__['include_group_names'] = [ws_group_a.display_name] |
| 58 | + # TODO: Move `include_object_permissions` to context like other `include_` attributes |
| 59 | + # Limit the considered permissions to the following objects: |
34 | 60 | installation_ctx.__dict__['include_object_permissions'] = [ |
35 | 61 | f"cluster-policies:{cluster_policy.policy_id}", |
36 | 62 | f"TABLE:{table.full_name}", |
37 | 63 | f"secrets:{secret_scope}", |
38 | 64 | ] |
39 | 65 |
|
40 | 66 | installation_ctx.workspace_installation.run() |
41 | | - |
42 | | - installation_ctx.deployed_workflows.run_workflow("migrate-groups") |
| 67 | + # The crawlers should run as part of the assessment. To minimize the crawling here, we only crawl what is necessary |
| 68 | + # Tables crawler fails on `tacl` cluster used by the apply and validate permission tasks |
| 69 | + installation_ctx.tables_crawler.snapshot(force_refresh=True) |
| 70 | + |
| 71 | + workflow = "migrate-groups" |
| 72 | + installation_ctx.deployed_workflows.run_workflow(workflow, skip_job_wait=True) |
| 73 | + assert installation_ctx.deployed_workflows.validate_step(workflow), f"Workflow failed: {workflow}" |
| 74 | + |
| 75 | + # Wrapper functions to wait for eventual consistency of API |
| 76 | + @retried(on=[KeyError], timeout=dt.timedelta(minutes=1)) |
| 77 | + def wait_for_workspace_group_to_exists(display_name: str) -> bool: |
| 78 | + if installation_ctx.group_manager.has_workspace_group(display_name): |
| 79 | + return True |
| 80 | + raise KeyError(f"Group not found {display_name}") |
| 81 | + |
| 82 | + # The original workspace group should be renamed |
| 83 | + renamed_workspace_group_name = installation_ctx.renamed_group_prefix + ws_group.display_name |
| 84 | + assert wait_for_workspace_group_to_exists( |
| 85 | + renamed_workspace_group_name |
| 86 | + ), f"Workspace group not found: {renamed_workspace_group_name}" |
| 87 | + if installation_ctx.group_manager.has_workspace_group(ws_group.display_name): # Avoid wait on timeout |
| 88 | + with pytest.raises(TimeoutError): |
| 89 | + wait_for_workspace_group_to_exists(ws_group.display_name) # Expect to NOT exists |
| 90 | + |
| 91 | + schema_grants = installation_ctx.grants_crawler.for_schema_info(schema) |
| 92 | + assert {"USAGE", "OWN"} == schema_grants[acc_group.display_name], "Incorrect schema grants for migrated group" |
43 | 93 |
|
44 | 94 | # specific permissions api migrations are checked in different and smaller integration tests |
45 | | - found = installation_ctx.generic_permissions_support.load_as_dict("cluster-policies", cluster_policy.policy_id) |
46 | | - assert acc_group_a.display_name in found, "Group not found in cluster policies" |
47 | | - assert found[acc_group_a.display_name] == PermissionLevel.CAN_USE |
| 95 | + object_permissions = installation_ctx.generic_permissions_support.load_as_dict( |
| 96 | + "cluster-policies", cluster_policy.policy_id |
| 97 | + ) |
| 98 | + assert acc_group.display_name in object_permissions, "Group not found in cluster policies" |
| 99 | + assert object_permissions[acc_group.display_name] == PermissionLevel.CAN_USE |
48 | 100 |
|
49 | 101 | scope_permission = installation_ctx.secret_scope_acl_support.secret_scope_permission( |
50 | | - secret_scope, acc_group_a.display_name |
| 102 | + secret_scope, acc_group.display_name |
51 | 103 | ) |
52 | 104 | assert scope_permission == AclPermission.WRITE |
53 | 105 |
|
@@ -96,44 +148,3 @@ def test_running_legacy_validate_groups_permissions_job( |
96 | 148 |
|
97 | 149 | # assert the job does not throw any exception |
98 | 150 | installation_ctx.deployed_workflows.run_workflow("validate-groups-permissions") |
99 | | - |
100 | | - |
101 | | -def test_permissions_migration_for_group_with_same_name( |
102 | | - installation_ctx, |
103 | | - make_cluster_policy, |
104 | | - make_cluster_policy_permissions, |
105 | | -): |
106 | | - ws_group, acc_group = installation_ctx.make_ucx_group() |
107 | | - migrated_group = MigratedGroup.partial_info(ws_group, acc_group) |
108 | | - cluster_policy = make_cluster_policy() |
109 | | - make_cluster_policy_permissions( |
110 | | - object_id=cluster_policy.policy_id, |
111 | | - permission_level=PermissionLevel.CAN_USE, |
112 | | - group_name=migrated_group.name_in_workspace, |
113 | | - ) |
114 | | - |
115 | | - schema_a = installation_ctx.make_schema() |
116 | | - table_a = installation_ctx.make_table(schema_name=schema_a.name) |
117 | | - installation_ctx.make_grant(migrated_group.name_in_workspace, 'USAGE', schema_info=schema_a) |
118 | | - installation_ctx.make_grant(migrated_group.name_in_workspace, 'OWN', schema_info=schema_a) |
119 | | - installation_ctx.make_grant(migrated_group.name_in_workspace, 'SELECT', table_info=table_a) |
120 | | - |
121 | | - installation_ctx.workspace_installation.run() |
122 | | - |
123 | | - installation_ctx.deployed_workflows.run_workflow("migrate-groups") |
124 | | - |
125 | | - object_permissions = installation_ctx.generic_permissions_support.load_as_dict( |
126 | | - "cluster-policies", cluster_policy.policy_id |
127 | | - ) |
128 | | - new_schema_grants = installation_ctx.grants_crawler.for_schema_info(schema_a) |
129 | | - |
130 | | - if {"USAGE", "OWN"} != new_schema_grants[migrated_group.name_in_account] or object_permissions[ |
131 | | - migrated_group.name_in_account |
132 | | - ] != PermissionLevel.CAN_USE: |
133 | | - installation_ctx.deployed_workflows.relay_logs("migrate-groups") |
134 | | - assert {"USAGE", "OWN"} == new_schema_grants[ |
135 | | - migrated_group.name_in_account |
136 | | - ], "Incorrect schema grants for migrated group" |
137 | | - assert ( |
138 | | - object_permissions[migrated_group.name_in_account] == PermissionLevel.CAN_USE |
139 | | - ), "Incorrect permissions for migrated group" |
|
0 commit comments