@@ -17,12 +17,14 @@ export class DataLakeEnrollment extends cdk.Construct {
1717 public DataSetName : string ;
1818 private CoarseAthenaAccessPolicy : iam . ManagedPolicy ;
1919 private CoarseResourceAccessPolicy : iam . ManagedPolicy ;
20+ private CoarseIamPolciesApplied : boolean ;
2021
2122 constructor ( scope : cdk . Construct , id : string , props : DataLakeEnrollment . DataLakeEnrollmentProps ) {
2223 super ( scope , id ) ;
2324
2425
2526 this . DataSetName = props . DataSetName ;
27+ this . CoarseIamPolciesApplied = false ;
2628
2729 }
2830
@@ -224,21 +226,59 @@ export class DataLakeEnrollment extends cdk.Construct {
224226 }
225227
226228
227- private createLakeFormationPermission ( resourceId : string , dataLakePrincipal : lakeformation . CfnPermissions . DataLakePrincipalProperty ,
228- resource : lakeformation . CfnPermissions . ResourceProperty , permissions : string [ ] , grantablePremissions : string [ ] ) {
229-
230- new lakeformation . CfnPermissions ( this , resourceId , {
231- dataLakePrincipal : dataLakePrincipal ,
232- resource : resource ,
233- permissions : permissions ,
234- permissionsWithGrantOption : grantablePremissions
235- } ) ;
229+ public grantTableWithColumnPermissions ( principal : iam . IPrincipal , permissionGrant : DataLakeEnrollment . TableWithColumnPermissionGrant ) {
230+
231+ const coreGrant = this . setupIamAndLakeFormationDatabasePermissionForPrincipal ( principal , permissionGrant . DatabasePermissions , permissionGrant . GrantableDatabasePermissions ) ;
232+
233+ const wildcardProperty : lakeformation . CfnPermissions . ColumnWildcardProperty = {
234+ excludedColumnNames : permissionGrant . columns
235+ } ;
236+
237+ var tableWithColumnsProperty : lakeformation . CfnPermissions . TableWithColumnsResourceProperty = {
238+ columnNames : permissionGrant . columns ,
239+ databaseName : this . DataEnrollment . Dataset_Datalake . databaseName ,
240+ name : permissionGrant . table
241+ } ;
242+
243+ if ( permissionGrant . wildCardFilter === null ) {
244+ tableWithColumnsProperty = {
245+ columnNames : permissionGrant . columns ,
246+ databaseName : this . DataEnrollment . Dataset_Datalake . databaseName ,
247+ name : permissionGrant . table
248+ } ;
249+ } else {
250+
251+ if ( permissionGrant . wildCardFilter == DataLakeEnrollment . TableWithColumnFilter . Include ) {
252+ tableWithColumnsProperty = {
253+ columnNames : permissionGrant . columns ,
254+ databaseName : this . DataEnrollment . Dataset_Datalake . databaseName ,
255+ name : permissionGrant . table
256+ } ;
257+ }
258+
259+ if ( permissionGrant . wildCardFilter == DataLakeEnrollment . TableWithColumnFilter . Exclude ) {
260+ tableWithColumnsProperty = {
261+ databaseName : this . DataEnrollment . Dataset_Datalake . databaseName ,
262+ name : permissionGrant . table ,
263+ columnWildcard : {
264+ excludedColumnNames : permissionGrant . columns
265+ }
266+ } ;
267+ }
268+
269+ }
270+
271+ const tableWithColumnResourceProperty : lakeformation . CfnPermissions . ResourceProperty = {
272+ tableWithColumnsResource : tableWithColumnsProperty
273+ } ;
274+
275+ this . createLakeFormationPermission ( `${ coreGrant . grantIdPrefix } -${ permissionGrant . table } -databaseTableWithColumnGrant` , coreGrant . dataLakePrincipal , tableWithColumnResourceProperty , permissionGrant . TableColumnPermissions , permissionGrant . GrantableTableColumnPermissions )
276+
277+
236278 }
237279
238- public grantLakeFormationPermissions ( principal : iam . IPrincipal , permissionGrant : DataLakeEnrollment . LakeFormationPermissionGrant ) {
239-
280+ public grantDatabasePermission ( principal : iam . IPrincipal , permissionGrant : DataLakeEnrollment . DatabasePermissionGrant ) {
240281
241- this . grantCoarseIamRead ( principal ) ;
242282
243283 var grantIdPrefix = ""
244284 var dataLakePrincipal : lakeformation . CfnPermissions . DataLakePrincipalProperty = {
@@ -260,10 +300,17 @@ export class DataLakeEnrollment extends cdk.Construct {
260300 if ( resolvedPrincipalType === iam . User ) {
261301 const resolvedPrincipal = principal as iam . User ;
262302 grantIdPrefix = `${ resolvedPrincipal . userName } -${ this . DataSetName } `
263- dataLakePrincipal = { dataLakePrincipalIdentifier : resolvedPrincipal . userName } ;
303+ dataLakePrincipal = { dataLakePrincipalIdentifier : resolvedPrincipal . userArn } ;
264304 }
265305
266- this . createLakeFormationPermission ( `${ grantIdPrefix } -databaseGrant` , dataLakePrincipal , databaseResourceProperty , permissionGrant . DatabasePermissions , permissionGrant . GrantableDatabasePermissions )
306+ this . createLakeFormationPermission ( `${ grantIdPrefix } -databaseGrant` , dataLakePrincipal , databaseResourceProperty , permissionGrant . DatabasePermissions , permissionGrant . GrantableDatabasePermissions )
307+
308+ }
309+
310+
311+ public grantTablePermissions ( principal : iam . IPrincipal , permissionGrant : DataLakeEnrollment . TablePermissionGrant ) {
312+
313+ const coreGrant = this . setupIamAndLakeFormationDatabasePermissionForPrincipal ( principal , permissionGrant . DatabasePermissions , permissionGrant . GrantableDatabasePermissions ) ;
267314
268315 permissionGrant . tables . forEach ( table => {
269316 var tableResourceProperty : lakeformation . CfnPermissions . ResourceProperty = {
@@ -272,16 +319,53 @@ export class DataLakeEnrollment extends cdk.Construct {
272319 databaseName : this . DataEnrollment . Dataset_Datalake . databaseName
273320 }
274321 } ;
275- this . createLakeFormationPermission ( `${ grantIdPrefix } -${ table } -databaseTableGrant` , dataLakePrincipal , tableResourceProperty , permissionGrant . TablePermissions , permissionGrant . TablePermissions )
322+ this . createLakeFormationPermission ( `${ coreGrant . grantIdPrefix } -${ table } -databaseTableGrant` , coreGrant . dataLakePrincipal , tableResourceProperty , permissionGrant . TablePermissions , permissionGrant . GrantableTablePermissions )
276323 } ) ;
277324
278325 }
279326
280- private determinePrincipalType ( principal : iam . IPrincipal ) {
327+
328+ public grantCoarseIamRead ( principal : iam . IPrincipal ) {
329+
330+
331+ const resolvedPrincipalType = this . determinePrincipalType ( principal ) ;
332+
333+ if ( resolvedPrincipalType === iam . Role ) {
334+ this . CoarseAthenaAccessPolicy . attachToRole ( principal as iam . Role ) ;
335+ this . CoarseResourceAccessPolicy . attachToRole ( principal as iam . Role ) ;
336+ this . CoarseIamPolciesApplied = true ;
337+ return ;
338+ }
339+
340+ if ( resolvedPrincipalType === iam . User ) {
341+ this . CoarseAthenaAccessPolicy . attachToUser ( principal as iam . User ) ;
342+ this . CoarseResourceAccessPolicy . attachToUser ( principal as iam . User ) ;
343+ this . CoarseIamPolciesApplied = true ;
344+ return ;
345+ }
346+
347+
348+
349+
350+
351+ }
352+
353+
354+
355+ private createLakeFormationPermission ( resourceId : string , dataLakePrincipal : lakeformation . CfnPermissions . DataLakePrincipalProperty , resource : lakeformation . CfnPermissions . ResourceProperty , permissions : string [ ] , grantablePremissions : string [ ] ) {
356+
357+ new lakeformation . CfnPermissions ( this , resourceId , {
358+ dataLakePrincipal : dataLakePrincipal ,
359+ resource : resource ,
360+ permissions : permissions ,
361+ permissionsWithGrantOption : grantablePremissions
362+ } ) ;
363+ }
364+ private determinePrincipalType ( principal : iam . IPrincipal ) {
281365
282366 if ( principal instanceof iam . Role ) {
283367 //return principal as iam.Role;
284- return iam . Role ;
368+ return iam . Role ;
285369 }
286370
287371 if ( principal instanceof iam . User ) {
@@ -290,45 +374,56 @@ export class DataLakeEnrollment extends cdk.Construct {
290374 }
291375
292376 if ( principal instanceof cdk . Resource ) {
293-
377+
294378 try {
295- const user = principal as iam . User ;
379+ const user = principal as iam . User ;
296380 return iam . User ;
297381 } catch ( exception ) {
298382 console . log ( exception ) ;
299383 }
300384 try {
301385 const role = principal as iam . Role ;
302- return iam . Role ;
386+ return iam . Role ;
303387 } catch ( exception ) {
304388 console . log ( exception ) ;
305389 }
306390 }
307-
391+
308392 throw ( "Unable to deterimine principal type..." ) ;
309393
310394 }
311-
395+ private setupIamAndLakeFormationDatabasePermissionForPrincipal ( principal : iam . IPrincipal , databasePermissions : Array < DataLakeEnrollment . DatabasePermission > , grantableDatabasePermissions : Array < DataLakeEnrollment . DatabasePermission > ) {
312396
313- public grantCoarseIamRead ( principal : iam . IPrincipal ) {
397+ this . grantCoarseIamRead ( principal ) ;
398+
399+ var grantIdPrefix = ""
400+ var dataLakePrincipal : lakeformation . CfnPermissions . DataLakePrincipalProperty = {
401+ dataLakePrincipalIdentifier : ""
402+ } ;
403+ var databaseResourceProperty : lakeformation . CfnPermissions . ResourceProperty = {
404+ //dataLocationResource: {resourceArn: this.DataEnrollment.DataLakeBucketName},
405+ databaseResource : { name : this . DataEnrollment . Dataset_Datalake . databaseName }
406+ } ;
314407
315408 const resolvedPrincipalType = this . determinePrincipalType ( principal ) ;
316409
317- if ( resolvedPrincipalType === iam . Role ) {
318- this . CoarseAthenaAccessPolicy . attachToRole ( principal as iam . Role ) ;
319- this . CoarseResourceAccessPolicy . attachToRole ( principal as iam . Role ) ;
320- return ;
410+ if ( resolvedPrincipalType === iam . Role ) {
411+ const resolvedPrincipal = principal as iam . Role ;
412+ grantIdPrefix = ` ${ resolvedPrincipal . roleArn } - ${ this . DataSetName } `
413+ dataLakePrincipal = { dataLakePrincipalIdentifier : resolvedPrincipal . roleArn } ;
321414 }
322415
323416 if ( resolvedPrincipalType === iam . User ) {
324- this . CoarseAthenaAccessPolicy . attachToUser ( principal as iam . User ) ;
325- this . CoarseResourceAccessPolicy . attachToUser ( principal as iam . User ) ;
326- return ;
417+ const resolvedPrincipal = principal as iam . User ;
418+ grantIdPrefix = ` ${ resolvedPrincipal . userName } - ${ this . DataSetName } `
419+ dataLakePrincipal = { dataLakePrincipalIdentifier : resolvedPrincipal . userArn } ;
327420 }
328-
329- throw ( "Unable to attach policy. Principal is not a user or role." ) ;
330421
331- }
422+ this . grantDatabasePermission ( principal , { DatabasePermissions : databasePermissions , GrantableDatabasePermissions : grantableDatabasePermissions } ) ;
423+
424+ return { grantIdPrefix : grantIdPrefix , dataLakePrincipal : dataLakePrincipal } ;
425+ }
426+
332427}
333428
334429
@@ -352,20 +447,41 @@ export namespace DataLakeEnrollment
352447 Insert = 'INSERT' ,
353448 }
354449
450+ export enum TableWithColumnFilter {
451+ Include = "Include" ,
452+ Exclude = "Exclude"
453+ }
454+
355455 export interface DataLakeEnrollmentProps extends cdk . StackProps {
356456 dataLakeBucket : s3 . Bucket ;
357457 GlueScriptPath : string ;
358458 GlueScriptArguments : any ;
359459 DataSetName : string ;
360460 }
361461
362- export interface LakeFormationPermissionGrant {
462+ export interface DatabasePermissionGrant {
463+ DatabasePermissions : Array < DatabasePermission > ;
464+ GrantableDatabasePermissions : Array < DatabasePermission > ;
465+ }
466+
467+
468+ export interface TablePermissionGrant {
363469 tables : Array < string > ;
364470 DatabasePermissions : Array < DatabasePermission > ;
365471 GrantableDatabasePermissions : Array < DatabasePermission > ;
366472 TablePermissions : Array < TablePermission > ;
367473 GrantableTablePermissions : Array < TablePermission > ;
368474 }
475+
476+ export interface TableWithColumnPermissionGrant {
477+ table : string ;
478+ columns : Array < string > ;
479+ wildCardFilter ?: TableWithColumnFilter ;
480+ DatabasePermissions : Array < DatabasePermission > ;
481+ GrantableDatabasePermissions : Array < DatabasePermission > ;
482+ TableColumnPermissions : Array < TablePermission > ;
483+ GrantableTableColumnPermissions : Array < TablePermission > ;
484+ }
369485}
370486
371487
0 commit comments