|
2 | 2 | import json |
3 | 3 | import time |
4 | 4 | from pathlib import Path |
5 | | -from unittest.mock import create_autospec, patch |
| 5 | +from unittest.mock import create_autospec, patch, Mock |
6 | 6 |
|
7 | 7 | import pytest |
8 | 8 | import yaml |
9 | | -from databricks.sdk.service.provisioning import Workspace |
10 | 9 | from databricks.labs.blueprint.tui import MockPrompts |
11 | 10 | from databricks.sdk import AccountClient, WorkspaceClient |
12 | 11 | from databricks.sdk.errors import NotFound |
| 12 | +from databricks.sdk.errors.platform import BadRequest |
13 | 13 | from databricks.sdk.service import iam, jobs, sql |
14 | 14 | from databricks.sdk.service.catalog import ExternalLocationInfo |
15 | 15 | from databricks.sdk.service.compute import ClusterDetails, ClusterSource |
| 16 | +from databricks.sdk.service.provisioning import Workspace |
16 | 17 | from databricks.sdk.service.workspace import ObjectInfo, ObjectType |
17 | | -from databricks.sdk.errors.platform import BadRequest |
18 | 18 |
|
19 | | -from databricks.labs.ucx.assessment.aws import AWSResources |
| 19 | +from databricks.labs.ucx.assessment.aws import AWSResources, AWSRoleAction |
20 | 20 | from databricks.labs.ucx.aws.access import AWSResourcePermissions |
21 | 21 | from databricks.labs.ucx.azure.access import AzureResourcePermissions |
22 | 22 | from databricks.labs.ucx.azure.resources import AzureResources |
|
31 | 31 | create_uber_principal, |
32 | 32 | ensure_assessment_run, |
33 | 33 | installations, |
| 34 | + join_collection, |
34 | 35 | logs, |
35 | 36 | manual_workspace_info, |
36 | 37 | migrate_credentials, |
|
51 | 52 | validate_external_locations, |
52 | 53 | validate_groups_membership, |
53 | 54 | workflows, |
54 | | - join_collection, |
55 | 55 | ) |
56 | 56 | from databricks.labs.ucx.contexts.account_cli import AccountContext |
57 | 57 | from databricks.labs.ucx.contexts.workspace_cli import WorkspaceContext |
58 | | -from databricks.labs.ucx.hive_metastore import TablesCrawler |
| 58 | +from databricks.labs.ucx.hive_metastore import TablesCrawler, ExternalLocations |
| 59 | +from databricks.labs.ucx.hive_metastore.locations import ExternalLocation |
59 | 60 | from databricks.labs.ucx.hive_metastore.tables import Table |
60 | 61 | from databricks.labs.ucx.source_code.linters.files import LocalFileMigrator |
61 | 62 |
|
@@ -364,6 +365,79 @@ def test_migrate_credentials_aws(ws): |
364 | 365 | ws.storage_credentials.list.assert_called() |
365 | 366 |
|
366 | 367 |
|
| 368 | +def test_migrate_credentials_limit_azure(ws): |
| 369 | + azure_resources = create_autospec(AzureResources) |
| 370 | + external_locations = create_autospec(ExternalLocations) |
| 371 | + external_locations_mock = [] |
| 372 | + for i in range(200): |
| 373 | + external_locations_mock.append( |
| 374 | + ExternalLocation( |
| 375 | + location=f"abfss://container{i}@storage{i}.dfs.core.windows.net/folder{i}", table_count=i % 20 |
| 376 | + ) |
| 377 | + ) |
| 378 | + external_locations.snapshot.return_value = external_locations_mock |
| 379 | + prompts = MockPrompts({'.*': 'yes'}) |
| 380 | + ctx = WorkspaceContext(ws).replace( |
| 381 | + is_azure=True, |
| 382 | + azure_cli_authenticated=True, |
| 383 | + azure_subscription_id='test', |
| 384 | + azure_resources=azure_resources, |
| 385 | + external_locations=external_locations, |
| 386 | + ) |
| 387 | + migrate_credentials(ws, prompts, ctx=ctx) |
| 388 | + ws.storage_credentials.list.assert_called() |
| 389 | + azure_resources.storage_accounts.assert_called() |
| 390 | + |
| 391 | + external_locations_mock.append( |
| 392 | + ExternalLocation( |
| 393 | + location=f"abfss://container{201}@storage{201}.dfs.core.windows.net/folder{201}", table_count=25 |
| 394 | + ) |
| 395 | + ) |
| 396 | + with pytest.raises(RuntimeWarning): |
| 397 | + migrate_credentials(ws, prompts, ctx=ctx) |
| 398 | + |
| 399 | + |
| 400 | +def test_migrate_credentials_limit_aws(ws): |
| 401 | + aws_resources = create_autospec(AWSResources) |
| 402 | + external_locations = create_autospec(ExternalLocations) |
| 403 | + |
| 404 | + external_locations_mock = [] |
| 405 | + aws_role_actions_mock = [] |
| 406 | + for i in range(200): |
| 407 | + location = f"s3://labsawsbucket/{i}" |
| 408 | + role = f"arn:aws:iam::123456789012:role/role_name{i}" |
| 409 | + external_locations_mock.append(ExternalLocation(location=location, table_count=i % 20)) |
| 410 | + aws_role_actions_mock.append( |
| 411 | + AWSRoleAction( |
| 412 | + role_arn=role, |
| 413 | + privilege="READ_FILES", |
| 414 | + resource_path=location, |
| 415 | + resource_type="s3", |
| 416 | + ) |
| 417 | + ) |
| 418 | + external_locations.snapshot.return_value = external_locations_mock |
| 419 | + aws_resources.validate_connection.return_value = {"Account": "123456789012"} |
| 420 | + |
| 421 | + prompts = MockPrompts({'.*': 'yes'}) |
| 422 | + AWSResourcePermissions.load_uc_compatible_roles = Mock() |
| 423 | + AWSResourcePermissions.load_uc_compatible_roles.return_value = aws_role_actions_mock |
| 424 | + ctx = WorkspaceContext(ws).replace(is_aws=True, aws_resources=aws_resources, external_locations=external_locations) |
| 425 | + migrate_credentials(ws, prompts, ctx=ctx) |
| 426 | + ws.storage_credentials.list.assert_called() |
| 427 | + |
| 428 | + external_locations_mock.append(ExternalLocation(location="s3://labsawsbucket/201", table_count=25)) |
| 429 | + aws_role_actions_mock.append( |
| 430 | + AWSRoleAction( |
| 431 | + role_arn="arn:aws:iam::123456789012:role/role_name201", |
| 432 | + privilege="READ_FILES", |
| 433 | + resource_path="s3://labsawsbucket/201", |
| 434 | + resource_type="s3", |
| 435 | + ) |
| 436 | + ) |
| 437 | + with pytest.raises(RuntimeWarning): |
| 438 | + migrate_credentials(ws, prompts, ctx=ctx) |
| 439 | + |
| 440 | + |
367 | 441 | def test_create_master_principal_not_azure(ws): |
368 | 442 | ws.config.is_azure = False |
369 | 443 | ws.config.is_aws = False |
|
0 commit comments