|
4 | 4 |
|
5 | 5 | import json |
6 | 6 | import logging |
7 | | -from datetime import datetime, timedelta, timezone |
8 | 7 | from typing import List, Optional |
9 | 8 |
|
10 | 9 | import botocore.exceptions |
@@ -198,7 +197,6 @@ def _register_s3_with_lake_formation( |
198 | 197 | register_params["UseServiceLinkedRole"] = True |
199 | 198 | else: |
200 | 199 | register_params["RoleArn"] = role_arn |
201 | | - # print(register_params) |
202 | 200 | client.register_resource(**register_params) |
203 | 201 | logger.info(f"Successfully registered S3 location: {resource_arn}") |
204 | 202 | return True |
@@ -399,7 +397,7 @@ def enable_lake_formation( |
399 | 397 | 3. Registers the offline store S3 location as data lake location |
400 | 398 | 4. Grants the execution role permissions on the Glue table |
401 | 399 | 5. Optionally revokes IAMAllowedPrincipal permissions from the Glue table |
402 | | - 6. Prints optional S3 deny bucket policy |
| 400 | + 6. Prints recommended S3 deny bucket policy |
403 | 401 |
|
404 | 402 | Parameters: |
405 | 403 | disable_hybrid_access_mode: If True, revokes IAMAllowedPrincipal permissions |
@@ -540,7 +538,9 @@ def enable_lake_formation( |
540 | 538 | "hybrid_access_mode_disabled": False |
541 | 539 | } |
542 | 540 |
|
543 | | - # Execute Lake Formation setup with fail-fast behavior |
| 541 | + # Execute Lake Formation setup with fail-fast behavior. |
| 542 | + # On failure, log warnings for incomplete steps before re-raising. |
| 543 | + phase_error = None |
544 | 544 |
|
545 | 545 | # Phase 1: Register S3 with Lake Formation |
546 | 546 | try: |
@@ -568,51 +568,60 @@ def enable_lake_formation( |
568 | 568 | role_arn=registration_role_arn, |
569 | 569 | ) |
570 | 570 | except Exception as e: |
571 | | - raise RuntimeError( |
| 571 | + phase_error = RuntimeError( |
572 | 572 | f"Failed to register S3 location with Lake Formation. " |
573 | 573 | f"Subsequent phases skipped. Results: {results}. Error: {e}" |
574 | | - ) from e |
575 | | - |
576 | | - if not results["s3_location_registered"]: |
577 | | - raise RuntimeError( |
578 | | - f"Failed to register S3 location with Lake Formation. " |
579 | | - f"Subsequent phases skipped. Results: {results}" |
580 | 574 | ) |
| 575 | + phase_error.__cause__ = e |
581 | 576 |
|
582 | 577 | # Phase 2: Grant Lake Formation permissions to the role |
583 | | - try: |
584 | | - results["lf_permissions_granted"] = self._grant_lake_formation_permissions( |
585 | | - role_arn_str, database_name_str, table_name_str, session, region |
586 | | - ) |
587 | | - except Exception as e: |
588 | | - raise RuntimeError( |
589 | | - f"Failed to grant Lake Formation permissions. " |
590 | | - f"Subsequent phases skipped. Results: {results}. Error: {e}" |
591 | | - ) from e |
592 | | - |
593 | | - if not results["lf_permissions_granted"]: |
594 | | - raise RuntimeError( |
595 | | - f"Failed to grant Lake Formation permissions. " |
596 | | - f"Subsequent phases skipped. Results: {results}" |
597 | | - ) |
598 | | - |
| 578 | + if phase_error is None: |
| 579 | + try: |
| 580 | + results["lf_permissions_granted"] = self._grant_lake_formation_permissions( |
| 581 | + role_arn_str, database_name_str, table_name_str, session, region |
| 582 | + ) |
| 583 | + except Exception as e: |
| 584 | + phase_error = RuntimeError( |
| 585 | + f"Failed to grant Lake Formation permissions. " |
| 586 | + f"Subsequent phases skipped. Results: {results}. Error: {e}" |
| 587 | + ) |
| 588 | + phase_error.__cause__ = e |
599 | 589 |
|
600 | 590 | # Phase 3: Revoke IAMAllowedPrincipal permissions |
601 | | - if disable_hybrid_access_mode: |
| 591 | + if phase_error is None and disable_hybrid_access_mode: |
602 | 592 | try: |
603 | 593 | results["hybrid_access_mode_disabled"] = self._revoke_iam_allowed_principal( |
604 | 594 | database_name_str, table_name_str, session, region |
605 | 595 | ) |
606 | 596 | except Exception as e: |
607 | | - raise RuntimeError( |
| 597 | + phase_error = RuntimeError( |
608 | 598 | f"Failed to revoke IAMAllowedPrincipal permissions. Results: {results}. Error: {e}" |
609 | | - ) from e |
610 | | - |
611 | | - if not results["hybrid_access_mode_disabled"]: |
612 | | - raise RuntimeError( |
613 | | - f"Failed to revoke IAMAllowedPrincipal permissions. Results: {results}" |
614 | 599 | ) |
615 | | - |
| 600 | + phase_error.__cause__ = e |
| 601 | + |
| 602 | + # Warn about any steps that were not completed |
| 603 | + if not results["s3_location_registered"]: |
| 604 | + logger.warning( |
| 605 | + "S3 location was not registered with Lake Formation. " |
| 606 | + "Re-run enable_lake_formation() after fixing the issue." |
| 607 | + ) |
| 608 | + if not results["lf_permissions_granted"]: |
| 609 | + logger.warning( |
| 610 | + "Lake Formation permissions were not granted to the " |
| 611 | + "execution role. Re-run enable_lake_formation() after fixing the issue." |
| 612 | + ) |
| 613 | + if not results["hybrid_access_mode_disabled"]: |
| 614 | + logger.warning( |
| 615 | + "Hybrid access mode was not disabled. IAM-based access " |
| 616 | + "to the Glue table is still allowed alongside Lake " |
| 617 | + "Formation permissions. To disable, re-run with " |
| 618 | + "disable_hybrid_access_mode=True. For more info: " |
| 619 | + "https://docs.aws.amazon.com/lake-formation/latest/dg/hybrid-access-mode.html" |
| 620 | + ) |
| 621 | + |
| 622 | + # Re-raise after warnings so the caller sees what was incomplete |
| 623 | + if phase_error is not None: |
| 624 | + raise phase_error |
616 | 625 |
|
617 | 626 | # Phase 4: Print S3 bucket policy |
618 | 627 | # Validate feature_group_arn is available for account ID extraction |
@@ -663,28 +672,6 @@ def enable_lake_formation( |
663 | 672 |
|
664 | 673 | logger.info(f"Lake Formation setup complete for {self.feature_group_name}: {results}") |
665 | 674 |
|
666 | | - # Warn about any steps that were not completed |
667 | | - if not results["s3_location_registered"]: |
668 | | - logger.warning( |
669 | | - "S3 location was not registered with Lake Formation. " |
670 | | - "Re-run enable_lake_formation() or manually register " |
671 | | - "the S3 location via the Lake Formation console." |
672 | | - ) |
673 | | - if not results["lf_permissions_granted"]: |
674 | | - logger.warning( |
675 | | - "Lake Formation permissions were not granted to the " |
676 | | - "execution role. Grant permissions manually via the " |
677 | | - "Lake Formation console or re-run the method after fixing the issue." |
678 | | - ) |
679 | | - if not results["hybrid_access_mode_disabled"]: |
680 | | - logger.warning( |
681 | | - "Hybrid access mode was not disabled. IAM-based access " |
682 | | - "to the Glue table is still allowed alongside Lake " |
683 | | - "Formation permissions. To disable, re-run with " |
684 | | - "disable_hybrid_access_mode=True. For more info: " |
685 | | - "https://docs.aws.amazon.com/lake-formation/latest/dg/hybrid-access-mode.html" |
686 | | - ) |
687 | | - |
688 | 675 | return results |
689 | 676 |
|
690 | 677 | @classmethod |
|
0 commit comments