Skip to content

Commit

Permalink
Merge branch 'master' into feature/enable-control-plane-logs
Browse files Browse the repository at this point in the history
  • Loading branch information
eduardomourar authored Jun 23, 2020
2 parents 876a012 + dde0ef5 commit da23fc4
Show file tree
Hide file tree
Showing 7 changed files with 863 additions and 0 deletions.
21 changes: 21 additions & 0 deletions packages/@aws-cdk/aws-efs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,27 @@ const fileSystem = new FileSystem(this, 'EfsFileSystem', {
});
```

### Access Point

An access point is an application-specific view into an EFS file system that applies an operating system user and
group, and a file system path, to any file system request made through the access point. The operating system user
and group override any identity information provided by the NFS client. The file system path is exposed as the
access point's root directory. Applications using the access point can only access data in its own directory and
below. To learn more, see [Mounting a File System Using EFS Access Points](https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html).

Use `AccessPoint` to create an access point:

```ts
new AccessPoint(stack, 'AccessPoint', {
fileSystem
});
```

By default, when you create an access point, the root(`/`) directory is exposed to the client connecting to
the access point. You may specify custom path with the `path` property. If `path` does not exist, it will be
created with the settings defined in the `creationInfo`. See
[Creating Access Points](https://docs.aws.amazon.com/efs/latest/ug/create-access-point.html) for more details.

### Connecting

To control who can access the EFS, use the `.connections` attribute. EFS has
Expand Down
164 changes: 164 additions & 0 deletions packages/@aws-cdk/aws-efs/lib/access-point.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import { Construct, IResource, Resource, Stack } from '@aws-cdk/core';
import { IFileSystem } from './efs-file-system';
import { CfnAccessPoint } from './efs.generated';

/**
* Represents an EFS AccessPoint
*/
export interface IAccessPoint extends IResource {
/**
* The ID of the AccessPoint
*
* @attribute
*/
readonly accessPointId: string;

/**
* The ARN of the AccessPoint
*
* @attribute
*/
readonly accessPointArn: string;
}

/**
* Permissions as POSIX ACL
*/
export interface Acl {
/**
* Specifies the POSIX user ID to apply to the RootDirectory. Accepts values from 0 to 2^32 (4294967295).
*/
readonly ownerUid: string;

/**
* Specifies the POSIX group ID to apply to the RootDirectory. Accepts values from 0 to 2^32 (4294967295).
*/
readonly ownerGid: string;

/**
* Specifies the POSIX permissions to apply to the RootDirectory, in the format of an octal number representing
* the file's mode bits.
*/
readonly permissions: string;
}

/**
* Represents the PosixUser
*/
export interface PosixUser {
/**
* The POSIX user ID used for all file system operations using this access point.
*/
readonly uid: string;

/**
* The POSIX group ID used for all file system operations using this access point.
*/
readonly gid: string;

/**
* Secondary POSIX group IDs used for all file system operations using this access point.
*
* @default - None
*/
readonly secondaryGids?: string[];
}

/**
* Properties for the AccessPoint
*/
export interface AccessPointProps {
/**
* The efs filesystem
*/
readonly fileSystem: IFileSystem;

/**
* Specifies the POSIX IDs and permissions to apply when creating the access point's root directory. If the
* root directory specified by `path` does not exist, EFS creates the root directory and applies the
* permissions specified here. If the specified `path` does not exist, you must specify `createAcl`.
*
* @default - None. The directory specified by `path` must exist.
*/
readonly createAcl?: Acl;

/**
* Specifies the path on the EFS file system to expose as the root directory to NFS clients using the access point
* to access the EFS file system
*
* @default '/'
*/
readonly path?: string;

/**
* The full POSIX identity, including the user ID, group ID, and any secondary group IDs, on the access point
* that is used for all file system operations performed by NFS clients using the access point.
*
* Specify this to enforce a user identity using an access point.
*
* @see - [Enforcing a User Identity Using an Access Point](https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html)
*
* @default - user identity not enforced
*/
readonly posixUser?: PosixUser;
}

/**
* Represents the AccessPoint
*/
export class AccessPoint extends Resource implements IAccessPoint {
/**
* Import an existing Access Point
*/
public static fromAccessPointId(scope: Construct, id: string, accessPointId: string): IAccessPoint {
class Import extends Resource implements IAccessPoint {
public readonly accessPointId = accessPointId;
public readonly accessPointArn = Stack.of(scope).formatArn({
service: 'elasticfilesystem',
resource: 'access-point',
resourceName: accessPointId,
});
}
return new Import(scope, id);
}

/**
* The ARN of the Access Point
* @attribute
*/
public readonly accessPointArn: string;

/**
* The ID of the Access Point
* @attribute
*/
public readonly accessPointId: string;

constructor(scope: Construct, id: string, props: AccessPointProps) {
super(scope, id);

const resource = new CfnAccessPoint(scope, 'Resource', {
fileSystemId: props.fileSystem.fileSystemId,
rootDirectory: {
creationInfo: props.createAcl ? {
ownerGid: props.createAcl.ownerGid,
ownerUid: props.createAcl.ownerUid,
permissions: props.createAcl.permissions,
} : undefined,
path: props.path,
},
posixUser: props.posixUser ? {
uid: props.posixUser.uid,
gid: props.posixUser.gid,
secondaryGids: props.posixUser.secondaryGids,
} : undefined,
});

this.accessPointId = resource.ref;
this.accessPointArn = Stack.of(scope).formatArn({
service: 'elasticfilesystem',
resource: 'access-point',
resourceName: this.accessPointId,
});
}
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-efs/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// AWS::EFS CloudFormation Resources:
export * from './access-point';
export * from './efs-file-system';
export * from './efs.generated';
6 changes: 6 additions & 0 deletions packages/@aws-cdk/aws-efs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"devDependencies": {
"@aws-cdk/assert": "0.0.0",
"cdk-build-tools": "0.0.0",
"cdk-integ-tools": "0.0.0",
"cfn2ts": "0.0.0",
"pkglint": "0.0.0"
},
Expand All @@ -88,6 +89,11 @@
"engines": {
"node": ">= 10.13.0 <13 || >=13.7.0"
},
"awslint": {
"exclude": [
"props-physical-name:@aws-cdk/aws-efs.AccessPointProps"
]
},
"stability": "experimental",
"maturity": "experimental",
"awscdkio": {
Expand Down
79 changes: 79 additions & 0 deletions packages/@aws-cdk/aws-efs/test/access-point.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { expect as expectCDK, haveResource } from '@aws-cdk/assert';
import * as ec2 from '@aws-cdk/aws-ec2';
import { Stack } from '@aws-cdk/core';
import { AccessPoint, FileSystem } from '../lib';

let stack: Stack;
let vpc: ec2.Vpc;
let fileSystem: FileSystem;

beforeEach(() => {
stack = new Stack();
vpc = new ec2.Vpc(stack, 'VPC');
fileSystem = new FileSystem(stack, 'EfsFileSystem', {
vpc,
});
});

test('default access point is created correctly', () => {
// WHEN
new AccessPoint(stack, 'MyAccessPoint', {
fileSystem,
});
// THEN
expectCDK(stack).to(haveResource('AWS::EFS::AccessPoint'));
});

test('import correctly', () => {
// WHEN
const ap = new AccessPoint(stack, 'MyAccessPoint', {
fileSystem,
});
const imported = AccessPoint.fromAccessPointId(stack, 'ImportedAccessPoint', ap.accessPointId);
// THEN
expect(imported.accessPointId).toEqual(ap.accessPointId);
});

test('custom access point is created correctly', () => {
// WHEN
new AccessPoint(stack, 'MyAccessPoint', {
fileSystem,
createAcl: {
ownerGid: '1000',
ownerUid: '1000',
permissions: '755',
},
path: '/export/share',
posixUser: {
gid: '1000',
uid: '1000',
secondaryGids: [
'1001',
'1002',
],
},

});
// THEN
expectCDK(stack).to(haveResource('AWS::EFS::AccessPoint', {
FileSystemId: {
Ref: 'EfsFileSystem37910666',
},
PosixUser: {
Gid: '1000',
SecondaryGids: [
'1001',
'1002',
],
Uid: '1000',
},
RootDirectory: {
CreationInfo: {
OwnerGid: '1000',
OwnerUid: '1000',
Permissions: '755',
},
Path: '/export/share',
},
}));
});
Loading

0 comments on commit da23fc4

Please sign in to comment.