|
1 | | -# Copyright 2019-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| 1 | +# Copyright 2019-2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
2 | 2 | # SPDX-License-Identifier: MIT-0 |
3 | 3 |
|
| 4 | +import sys |
4 | 5 | import boto3 |
| 6 | +import argparse |
| 7 | + |
| 8 | + |
| 9 | +# 0. Configure credentials and required parameters |
| 10 | +parser = argparse.ArgumentParser() |
| 11 | +parser.add_argument('-p', '--profile', help='AWS named profile name') |
| 12 | +parser.add_argument('-r', '--region', help='Region name') |
| 13 | +args = parser.parse_args() |
| 14 | + |
| 15 | +session_args = {} |
| 16 | +if args.profile is not None: |
| 17 | + session_args['profile_name'] = args.profile |
| 18 | + print(f"boto3 Session uses {args.profile} profile based on the argument.") |
| 19 | +if args.region is not None: |
| 20 | + session_args['region_name'] = args.region |
| 21 | + print(f"boto3 Session uses {args.region} region based on the argument.") |
| 22 | + |
| 23 | +session = boto3.Session(**session_args) |
| 24 | +sts = session.client('sts') |
| 25 | +account_id = sts.get_caller_identity().get('Account') |
| 26 | +print(f"- Account: {account_id}\n- Profile: {session.profile_name}\n- Region: {session.region_name}") |
| 27 | + |
| 28 | + |
| 29 | +def prompt(message): |
| 30 | + answer = input(message) |
| 31 | + if answer.lower() in ["n","no"]: |
| 32 | + sys.exit(0) |
| 33 | + elif answer.lower() not in ["y","yes"]: |
| 34 | + prompt(message) |
| 35 | + |
| 36 | + |
| 37 | +prompt(f"Are you sure to make modifications on Lake Formation permissions to use only IAM access control? (y/n): ") |
5 | 38 |
|
6 | | -session = boto3.Session() |
7 | 39 | glue = session.client('glue') |
8 | 40 | lakeformation = session.client('lakeformation') |
9 | 41 |
|
|
44 | 76 | for d in databases: |
45 | 77 | print(f"... Granting permissions on database {d['Name']} ...") |
46 | 78 |
|
| 79 | + # Skip database if it is a resource link |
| 80 | + if 'TargetDatabase' in d: |
| 81 | + print(f"Database {d['Name']} is skipped since it is a resource link.") |
| 82 | + continue |
| 83 | + |
47 | 84 | # 4.1. Grant ALL to IAM_ALLOWED_PRINCIPALS for existing databases |
48 | 85 | database_resource = {'Database': {'Name': d['Name']}} |
49 | 86 | lakeformation.grant_permissions(Principal=iam_allowed_principal, |
|
89 | 126 |
|
90 | 127 | for t in tables: |
91 | 128 | print(f"... Granting permissions on table {d['Name']} ...") |
| 129 | + |
| 130 | + # Skip table if it is a resource link |
| 131 | + if 'TargetTable' in t: |
| 132 | + print(f"Table {d['Name']} is skipped since it is a resource link.") |
| 133 | + continue |
| 134 | + |
92 | 135 | table_resource = {'Table': {'DatabaseName': d['Name'], 'Name': t['Name']}} |
93 | 136 | lakeformation.grant_permissions(Principal=iam_allowed_principal, |
94 | 137 | Resource=table_resource, |
95 | 138 | Permissions=['ALL'], |
96 | 139 | PermissionsWithGrantOption=[]) |
97 | 140 |
|
| 141 | +def get_catalog_id(resource): |
| 142 | + for key in resource.keys(): |
| 143 | + if isinstance(resource[key], dict): |
| 144 | + return get_catalog_id(resource[key]) |
| 145 | + elif 'CatalogId' == key: |
| 146 | + return resource[key] |
| 147 | + |
| 148 | + |
98 | 149 | # 5. Revoke all the permissions except IAM_ALLOWED_PRINCIPALS |
99 | 150 | print('5. Revoking all the permissions except IAM_ALLOWED_PRINCIPALS...') |
100 | 151 | res = lakeformation.list_permissions() |
|
105 | 156 | for p in permissions: |
106 | 157 | if p['Principal']['DataLakePrincipalIdentifier'] != 'IAM_ALLOWED_PRINCIPALS': |
107 | 158 | print(f"... Revoking permissions of {p['Principal']['DataLakePrincipalIdentifier']} on resource {p['Resource']} ...") |
| 159 | + |
| 160 | + # Skip resource if it is not owned by this account |
| 161 | + catalog_id = get_catalog_id(p['Resource']) |
| 162 | + if catalog_id != account_id: |
| 163 | + print(f"The resource '{p['Resource']}' is skipped since it is not owned by the account {account_id}.") |
| 164 | + continue |
108 | 165 | try: |
109 | 166 | lakeformation.revoke_permissions(Principal=p['Principal'], |
110 | 167 | Resource=p['Resource'], |
|
0 commit comments