Skip to content

Commit c00cda7

Browse files
authored
Use make_secret_scope fixture (#163)
1 parent 0ac7c58 commit c00cda7

File tree

4 files changed

+36
-70
lines changed

4 files changed

+36
-70
lines changed

src/databricks/labs/ucx/inventory/permissions.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from typing import Literal
99

1010
from databricks.sdk import WorkspaceClient
11+
from databricks.sdk.service import workspace
1112
from databricks.sdk.service.iam import AccessControlRequest, Group, ObjectPermissions
1213
from databricks.sdk.service.workspace import AclItem as SdkAclItem
1314
from ratelimit import limits, sleep_and_retry
@@ -23,7 +24,7 @@
2324
RolesAndEntitlements,
2425
)
2526
from databricks.labs.ucx.providers.groups_info import GroupMigrationState
26-
from databricks.labs.ucx.utils import ThreadedExecution, safe_get_acls
27+
from databricks.labs.ucx.utils import ThreadedExecution
2728

2829
logger = logging.getLogger(__name__)
2930

@@ -189,13 +190,13 @@ def _scope_permissions_applicator(self, request_payload: SecretsPermissionReques
189190
# the api might be inconsistent, therefore we need to check that the permissions were applied
190191
for _ in range(3):
191192
time.sleep(random.random() * 2)
192-
applied_acls = safe_get_acls(
193-
self._ws, scope_name=request_payload.object_id, group_name=_acl_item.principal
193+
applied_permission = self._secret_scope_permission(
194+
scope_name=request_payload.object_id, group_name=_acl_item.principal
194195
)
195-
assert applied_acls, f"Failed to apply permissions for {_acl_item.principal}"
196-
assert applied_acls.permission == _acl_item.permission, (
196+
assert applied_permission, f"Failed to apply permissions for {_acl_item.principal}"
197+
assert applied_permission == _acl_item.permission, (
197198
f"Failed to apply permissions for {_acl_item.principal}. "
198-
f"Expected: {_acl_item.permission}. Actual: {applied_acls.permission}"
199+
f"Expected: {_acl_item.permission}. Actual: {applied_permission}"
199200
)
200201

201202
@sleep_and_retry
@@ -323,3 +324,20 @@ def verify_applied_permissions(
323324
assert [t.all_permissions for t in dst_permissions] == [
324325
s.all_permissions for s in src_permissions
325326
], f"Target permissions were not applied correctly for {object_type}/{object_id}"
327+
328+
def verify_applied_scope_acls(
329+
self, scope_name: str, migration_state: GroupMigrationState, target: Literal["backup", "account"]
330+
):
331+
base_attr = "workspace" if target == "backup" else "backup"
332+
for mi in migration_state.groups:
333+
src_name = getattr(mi, base_attr).display_name
334+
dst_name = getattr(mi, target).display_name
335+
src_permission = self._secret_scope_permission(scope_name, src_name)
336+
dst_permission = self._secret_scope_permission(scope_name, dst_name)
337+
assert src_permission == dst_permission, "Scope ACLs were not applied correctly"
338+
339+
def _secret_scope_permission(self, scope_name: str, group_name: str) -> workspace.AclPermission | None:
340+
for acl in self._ws.secrets.list_acls(scope=scope_name):
341+
if acl.principal == group_name:
342+
return acl.permission
343+
return None

src/databricks/labs/ucx/utils.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55
from concurrent.futures import ALL_COMPLETED, ThreadPoolExecutor
66
from typing import Generic, TypeVar
77

8-
from databricks.sdk import WorkspaceClient
9-
from databricks.sdk.service.workspace import AclItem
10-
118
from databricks.labs.ucx.generic import StrEnum
129

1310
ExecutableResult = TypeVar("ExecutableResult")
@@ -83,10 +80,3 @@ class WorkspaceLevelEntitlement(StrEnum):
8380
DATABRICKS_SQL_ACCESS = "databricks-sql-access"
8481
ALLOW_CLUSTER_CREATE = "allow-cluster-create"
8582
ALLOW_INSTANCE_POOL_CREATE = "allow-instance-pool-create"
86-
87-
88-
def safe_get_acls(ws: WorkspaceClient, scope_name: str, group_name: str) -> AclItem | None:
89-
all_acls = ws.secrets.list_acls(scope=scope_name)
90-
for acl in all_acls:
91-
if acl.principal == group_name:
92-
return acl

tests/integration/conftest.py

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,7 @@
2323
CreateWarehouseRequestWarehouseType,
2424
GetWarehouseResponse,
2525
)
26-
from databricks.sdk.service.workspace import (
27-
AclPermission,
28-
ObjectInfo,
29-
ObjectType,
30-
SecretScope,
31-
)
26+
from databricks.sdk.service.workspace import ObjectInfo, ObjectType
3227

3328
from databricks.labs.ucx.config import InventoryTable
3429
from databricks.labs.ucx.inventory.types import RequestObjectType
@@ -53,15 +48,13 @@
5348
NUM_TEST_GROUPS = int(os.environ.get("NUM_TEST_GROUPS", 5))
5449
NUM_TEST_INSTANCE_PROFILES = int(os.environ.get("NUM_TEST_INSTANCE_PROFILES", 3))
5550
NUM_TEST_CLUSTERS = int(os.environ.get("NUM_TEST_CLUSTERS", 3))
56-
NUM_TEST_INSTANCE_POOLS = int(os.environ.get("NUM_TEST_INSTANCE_POOLS", 3))
5751
NUM_TEST_CLUSTER_POLICIES = int(os.environ.get("NUM_TEST_CLUSTER_POLICIES", 3))
5852
NUM_TEST_PIPELINES = int(os.environ.get("NUM_TEST_PIPELINES", 3))
5953
NUM_TEST_JOBS = int(os.environ.get("NUM_TEST_JOBS", 3))
6054
NUM_TEST_EXPERIMENTS = int(os.environ.get("NUM_TEST_EXPERIMENTS", 3))
6155
NUM_TEST_MODELS = int(os.environ.get("NUM_TEST_MODELS", 3))
6256
NUM_TEST_WAREHOUSES = int(os.environ.get("NUM_TEST_WAREHOUSES", 3))
6357
NUM_TEST_TOKENS = int(os.environ.get("NUM_TEST_TOKENS", 3))
64-
NUM_TEST_SECRET_SCOPES = int(os.environ.get("NUM_TEST_SECRET_SCOPES", 10))
6558

6659
NUM_THREADS = int(os.environ.get("NUM_TEST_THREADS", 20))
6760
UCX_TESTING_PREFIX = os.environ.get("UCX_TESTING_PREFIX", "ucx")
@@ -515,27 +508,6 @@ def tokens(ws: WorkspaceClient, env: EnvironmentInfo) -> list[AccessControlReque
515508
yield token_permissions
516509

517510

518-
@pytest.fixture
519-
def secret_scopes(ws: WorkspaceClient, env: EnvironmentInfo) -> list[SecretScope]:
520-
logger.debug("Creating test secret scopes")
521-
522-
for i in range(NUM_TEST_SECRET_SCOPES):
523-
ws.secrets.create_scope(f"{env.test_uid}-test-{i}")
524-
525-
test_secret_scopes = [s for s in ws.secrets.list_scopes() if s.name.startswith(env.test_uid)]
526-
527-
for scope in test_secret_scopes:
528-
random_permission = random.choice(list(AclPermission))
529-
random_ws_group, _ = random.choice(env.groups)
530-
ws.secrets.put_acl(scope.name, random_ws_group.display_name, random_permission)
531-
532-
yield test_secret_scopes
533-
534-
logger.debug("Deleting test secret scopes")
535-
executables = [partial(ws.secrets.delete_scope, s.name) for s in test_secret_scopes]
536-
Threader(executables).run()
537-
538-
539511
@pytest.fixture
540512
def workspace_objects(ws: WorkspaceClient, env: EnvironmentInfo) -> WorkspaceObjects:
541513
logger.info(f"Creating test workspace objects under /{env.test_uid}")
@@ -601,12 +573,10 @@ def verifiable_objects(
601573
models,
602574
warehouses,
603575
tokens,
604-
secret_scopes,
605576
workspace_objects,
606577
) -> list[tuple[list, str, RequestObjectType | None]]:
607578
_verifiable_objects = [
608579
(workspace_objects, "workspace_objects", None),
609-
(secret_scopes, "secret_scopes", None),
610580
(tokens, "tokens", RequestObjectType.AUTHORIZATION),
611581
(clusters, "cluster_id", RequestObjectType.CLUSTERS),
612582
(cluster_policies, "policy_id", RequestObjectType.CLUSTER_POLICIES),

tests/integration/test_e2e.py

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44

55
import pytest
66
from databricks.sdk import WorkspaceClient
7+
from databricks.sdk.service import workspace
78
from databricks.sdk.service.iam import (
89
AccessControlRequest,
910
AccessControlResponse,
1011
Permission,
1112
PermissionLevel,
1213
)
13-
from databricks.sdk.service.workspace import SecretScope
1414
from pyspark.errors import AnalysisException
1515

1616
from databricks.labs.ucx.config import (
@@ -24,7 +24,6 @@
2424
from databricks.labs.ucx.inventory.types import RequestObjectType
2525
from databricks.labs.ucx.providers.groups_info import GroupMigrationState
2626
from databricks.labs.ucx.toolkits.group_migration import GroupMigrationToolkit
27-
from databricks.labs.ucx.utils import safe_get_acls
2827

2928
from .utils import EnvironmentInfo, WorkspaceObjects
3029

@@ -68,27 +67,10 @@ def _verify_group_permissions(
6867
assert len(base_acls) == len(target_acls)
6968

7069
elif id_attribute == "secret_scopes":
71-
_scopes: list[SecretScope] = objects
72-
comparison_base = [
73-
getattr(mi, "workspace" if target == "backup" else "backup")
74-
for mi in toolkit.group_manager.migration_groups_provider.groups
75-
]
76-
77-
comparison_target = [getattr(mi, target) for mi in toolkit.group_manager.migration_groups_provider.groups]
78-
79-
for scope in _scopes:
80-
for base_group, target_group in zip(comparison_base, comparison_target, strict=True):
81-
base_acl = safe_get_acls(ws, scope.name, base_group.display_name)
82-
target_acl = safe_get_acls(ws, scope.name, target_group.display_name)
83-
84-
if base_acl:
85-
if not target_acl:
86-
msg = "Target ACL is empty, while base ACL is not"
87-
raise AssertionError(msg)
88-
89-
assert (
90-
base_acl.permission == target_acl.permission
91-
), f"Target permissions were not applied correctly for scope {scope.name}"
70+
for scope_name in objects:
71+
toolkit.permissions_manager.verify_applied_scope_acls(
72+
scope_name, toolkit.group_manager.migration_groups_provider, target
73+
)
9274

9375
elif id_attribute in ("tokens", "passwords"):
9476
_typed_objects: list[AccessControlRequest] = objects
@@ -149,6 +131,8 @@ def test_e2e(
149131
verifiable_objects: list[tuple[list, str, RequestObjectType | None]],
150132
make_instance_pool,
151133
make_instance_pool_permissions,
134+
make_secret_scope,
135+
make_secret_scope_acl,
152136
):
153137
logger.debug(f"Test environment: {env.test_uid}")
154138
ws_group = env.groups[0][0]
@@ -161,6 +145,10 @@ def test_e2e(
161145
)
162146
verifiable_objects.append(([pool], "instance_pool_id", RequestObjectType.INSTANCE_POOLS))
163147

148+
scope = make_secret_scope()
149+
make_secret_scope_acl(scope=scope, principal=ws_group.display_name, permission=workspace.AclPermission.WRITE)
150+
verifiable_objects.append(([scope], "secret_scopes", None))
151+
164152
config = MigrationConfig(
165153
connect=ConnectConfig.from_databricks_config(ws.config),
166154
inventory=InventoryConfig(table=inventory_table),

0 commit comments

Comments
 (0)