Skip to content

Commit

Permalink
Fix/database opt in (#1333)
Browse files Browse the repository at this point in the history
* Fixed potential issue with granting opt in on db with multiple tables.

* Fixed failing tests
  • Loading branch information
jamesstottmoj authored Sep 5, 2024
1 parent 8497745 commit 4c1bbd0
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 10 deletions.
43 changes: 35 additions & 8 deletions controlpanel/api/aws.py
Original file line number Diff line number Diff line change
Expand Up @@ -1250,10 +1250,13 @@ def create_lf_opt_in(self, database_name, table_name, principal_arn, catalog_id=
},
}

self.client.create_lake_formation_opt_in(
Resource=database_resource,
Principal={"DataLakePrincipalIdentifier": principal_arn},
)
opt_ins = self.list_lf_opt_ins(database_name, principal_arn, catalog_id)

if opt_ins["database"] is None:
self.client.create_lake_formation_opt_in(
Resource=database_resource,
Principal={"DataLakePrincipalIdentifier": principal_arn},
)

self.client.create_lake_formation_opt_in(
Resource=table_resource,
Expand All @@ -1277,16 +1280,40 @@ def delete_lf_opt_in(self, database_name, table_name, principal_arn, catalog_id=
},
}

self.client.delete_lake_formation_opt_in(
Resource=database_resource,
Principal={"DataLakePrincipalIdentifier": principal_arn},
)
opt_ins = self.list_lf_opt_ins(database_name, principal_arn, catalog_id)

if len(opt_ins["tables"]) == 1:
self.client.delete_lake_formation_opt_in(
Resource=database_resource,
Principal={"DataLakePrincipalIdentifier": principal_arn},
)

self.client.delete_lake_formation_opt_in(
Resource=table_resource,
Principal={"DataLakePrincipalIdentifier": principal_arn},
)

def list_lf_opt_ins(self, database_name, principal_arn, catalog_id=None):
catalog_id = catalog_id or settings.AWS_DATA_ACCOUNT_ID
result = {
"database": None,
"tables": [],
}

response = self.client.list_lake_formation_opt_ins(
Principal={"DataLakePrincipalIdentifier": principal_arn}
)["LakeFormationOptInsInfoList"]

for resource_object in response:
resource = resource_object["Resource"]
if "Database" in resource and resource["Database"]["Name"] == database_name:
result["database"] = resource
elif "Table" in resource:
if resource["Table"]["DatabaseName"] == database_name:
result["tables"].append(resource)

return result


class AWSGlue(AWSService):

Expand Down
12 changes: 10 additions & 2 deletions tests/frontend/views/test_databases.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,16 @@

# Mocked botocore _make_api_call function
def mock_make_api_call(self, operation_name, kwarg):
if operation_name == "CreateLakeFormationOptIn":
return {}
op_names = [
{"CreateLakeFormationOptIn": {}},
{"DeleteLakeFormationOptIn": {}},
{"ListLakeFormationOptIns": {"LakeFormationOptInsInfoList": []}},
]

for operation in op_names:
if operation_name in operation:
return operation[operation_name]

# If we don't want to patch the API call
return orig(self, operation_name, kwarg)

Expand Down

0 comments on commit 4c1bbd0

Please sign in to comment.