Skip to content

Commit

Permalink
Merge branch 'master' into xian13/codebuild-support-standard-5_0_image
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Jan 11, 2021
2 parents 564919a + cc745f8 commit e2f29c9
Show file tree
Hide file tree
Showing 33 changed files with 803 additions and 85 deletions.
4 changes: 4 additions & 0 deletions allowed-breaking-changes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,7 @@ incompatible-argument:@aws-cdk/aws-ecs.FargateTaskDefinition.<initializer>
incompatible-argument:@aws-cdk/aws-ecs.FargateTaskDefinition.addVolume
incompatible-argument:@aws-cdk/aws-ecs.TaskDefinition.<initializer>
incompatible-argument:@aws-cdk/aws-ecs.TaskDefinition.addVolume

# We made properties optional and it's really fine but our differ doesn't think so.
weakened:@aws-cdk/cloud-assembly-schema.DockerImageSource
weakened:@aws-cdk/cloud-assembly-schema.FileSource
28 changes: 28 additions & 0 deletions packages/@aws-cdk/aws-iam/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,34 @@ const provider = new iam.OpenIdConnectProvider(this, 'MyProvider', {
const principal = new iam.OpenIdConnectPrincipal(provider);
```

## Users

IAM manages users for your AWS account. To create a new user:

```ts
const user = new User(this, 'MyUser');
```

To import an existing user by name [with path](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-friendly-names):

```ts
const user = User.fromUserName(stack, 'MyImportedUserByName', 'johnsmith');
```

To import an existing user by ARN:

```ts
const user = User.fromUserArn(this, 'MyImportedUserByArn', 'arn:aws:iam::123456789012:user/johnsmith');
```

To import an existing user by attributes:

```ts
const user = User.fromUserAttributes(stack, 'MyImportedUserByAttributes', {
userArn: 'arn:aws:iam::123456789012:user/johnsmith',
});
```

## Features

* Policy name uniqueness is enforced. If two policies by the same name are attached to the same
Expand Down
44 changes: 39 additions & 5 deletions packages/@aws-cdk/aws-iam/lib/user.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Aws, Lazy, Resource, SecretValue, Stack } from '@aws-cdk/core';
import { Arn, Aws, Lazy, Resource, SecretValue, Stack } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { IGroup } from './group';
import { CfnUser } from './iam.generated';
Expand Down Expand Up @@ -119,6 +119,18 @@ export interface UserProps {
readonly passwordResetRequired?: boolean;
}

/**
* Represents a user defined outside of this stack.
*/
export interface UserAttributes {
/**
* The ARN of the user.
*
* Format: arn:<partition>:iam::<account-id>:user/<user-name-with-path>
*/
readonly userArn: string;
}

/**
* Define a new IAM user
*/
Expand All @@ -131,20 +143,42 @@ export class User extends Resource implements IIdentity, IUser {
* @param userName the username of the existing user to import
*/
public static fromUserName(scope: Construct, id: string, userName: string): IUser {
const arn = Stack.of(scope).formatArn({
const userArn = Stack.of(scope).formatArn({
service: 'iam',
region: '',
resource: 'user',
resourceName: userName,
});

return User.fromUserAttributes(scope, id, { userArn });
}

/**
* Import an existing user given a user ARN.
*
* @param scope construct scope
* @param id construct id
* @param userArn the ARN of an existing user to import
*/
public static fromUserArn(scope: Construct, id: string, userArn: string): IUser {
return User.fromUserAttributes(scope, id, { userArn });
}

/**
* Import an existing user given user attributes.
*
* @param scope construct scope
* @param id construct id
* @param attrs the attributes of the user to import
*/
public static fromUserAttributes(scope: Construct, id: string, attrs: UserAttributes): IUser {
class Import extends Resource implements IUser {
public readonly grantPrincipal: IPrincipal = this;
public readonly principalAccount = Aws.ACCOUNT_ID;
public readonly userName: string = userName;
public readonly userArn: string = arn;
public readonly userName: string = Arn.extractResourceName(attrs.userArn, 'user');
public readonly userArn: string = attrs.userArn;
public readonly assumeRoleAction: string = 'sts:AssumeRole';
public readonly policyFragment: PrincipalPolicyFragment = new ArnPrincipal(arn).policyFragment;
public readonly policyFragment: PrincipalPolicyFragment = new ArnPrincipal(attrs.userArn).policyFragment;
private readonly attachedPolicies = new AttachedPolicies();
private defaultPolicy?: Policy;

Expand Down
13 changes: 12 additions & 1 deletion packages/@aws-cdk/aws-iam/test/integ.user.expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,22 @@
"Type": "AWS::IAM::User",
"Properties": {
"LoginProfile": {
"Password": "1234",
"Password": "Test1234567890!",
"PasswordResetRequired": true
},
"UserName": "benisrae"
}
}
},
"Outputs": {
"NameForUserImportedByArn": {
"Value": "rossrhodes"
},
"NameForUserImportedByAttributes": {
"Value": "johndoe"
},
"NameForUserImportedByName": {
"Value": "janedoe"
}
}
}
14 changes: 12 additions & 2 deletions packages/@aws-cdk/aws-iam/test/integ.user.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { App, SecretValue, Stack } from '@aws-cdk/core';
import { App, CfnOutput, SecretValue, Stack } from '@aws-cdk/core';
import { User } from '../lib';

const app = new App();
Expand All @@ -7,8 +7,18 @@ const stack = new Stack(app, 'aws-cdk-iam-user');

new User(stack, 'MyUser', {
userName: 'benisrae',
password: SecretValue.plainText('1234'),
password: SecretValue.plainText('Test1234567890!'),
passwordResetRequired: true,
});

const userImportedByArn = User.fromUserArn(stack, 'ImportedUserByArn', 'arn:aws:iam::123456789012:user/rossrhodes');
const userImportedByAttributes = User.fromUserAttributes(stack, 'ImportedUserByAttributes', {
userArn: 'arn:aws:iam::123456789012:user/johndoe',
});
const userImportedByName = User.fromUserName(stack, 'ImportedUserByName', 'janedoe');

new CfnOutput(stack, 'NameForUserImportedByArn', { value: userImportedByArn.userName });
new CfnOutput(stack, 'NameForUserImportedByAttributes', { value: userImportedByAttributes.userName });
new CfnOutput(stack, 'NameForUserImportedByName', { value: userImportedByName.userName });

app.synth();
28 changes: 27 additions & 1 deletion packages/@aws-cdk/aws-iam/test/user.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe('IAM user', () => {
});
});

test('imported user has an ARN', () => {
test('user imported by user name has an ARN', () => {
// GIVEN
const stack = new Stack();

Expand All @@ -94,6 +94,32 @@ describe('IAM user', () => {
});
});

test('user imported by user ARN has a name', () => {
// GIVEN
const stack = new Stack();
const userName = 'MyUserName';

// WHEN
const user = User.fromUserArn(stack, 'import', `arn:aws:iam::account-id:user/${userName}`);

// THEN
expect(stack.resolve(user.userName)).toStrictEqual(userName);
});

test('user imported by user attributes has a name', () => {
// GIVEN
const stack = new Stack();
const userName = 'MyUserName';

// WHEN
const user = User.fromUserAttributes(stack, 'import', {
userArn: `arn:aws:iam::account-id:user/${userName}`,
});

// THEN
expect(stack.resolve(user.userName)).toStrictEqual(userName);
});

test('add to policy of imported user', () => {
// GIVEN
const stack = new Stack();
Expand Down
3 changes: 3 additions & 0 deletions packages/@aws-cdk/aws-lambda/lib/code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@ export class AssetCode extends Code {
path: this.path,
...this.options,
});
} else if (cdk.Stack.of(this.asset) !== cdk.Stack.of(scope)) {
throw new Error(`Asset is already associated with another stack '${cdk.Stack.of(this.asset).stackName}'. ` +
'Create a new Code instance for every stack.');
}

if (!this.asset.isZipArchive) {
Expand Down
20 changes: 20 additions & 0 deletions packages/@aws-cdk/aws-lambda/test/code.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,26 @@ describe('code', () => {
},
}, ResourcePart.CompleteDefinition);
});

test('fails if asset is bound with a second stack', () => {
// GIVEN
const asset = lambda.Code.fromAsset(path.join(__dirname, 'my-lambda-handler'));

const app = new cdk.App();
const stack1 = new cdk.Stack(app, 'Stack1');
new lambda.Function(stack1, 'Func', {
code: asset,
runtime: lambda.Runtime.NODEJS_10_X,
handler: 'foom',
});

const stack2 = new cdk.Stack(app, 'Stack2');
expect(() => new lambda.Function(stack2, 'Func', {
code: asset,
runtime: lambda.Runtime.NODEJS_10_X,
handler: 'foom',
})).toThrow(/already associated/);
});
});

describe('lambda.Code.fromCfnParameters', () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-s3-deployment/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ size of the AWS Lambda resource handler.
## Development
The custom resource is implemented in Python 3.6 in order to be able to leverage
the AWS CLI for "aws sync". The code is under [`lambda/src`](./lambda/src) and
unit tests are under [`lambda/test`](./lambda/test).
the AWS CLI for "aws sync". The code is under [`lib/lambda`](https://github.com/aws/aws-cdk/tree/master/packages/%40aws-cdk/aws-s3-deployment/lib/lambda) and
unit tests are under [`test/lambda`](https://github.com/aws/aws-cdk/tree/master/packages/%40aws-cdk/aws-s3-deployment/test/lambda).
This package requires Python 3.6 during build time in order to create the custom
resource Lambda bundle and test it. It also relies on a few bash scripts, so
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,42 @@ export interface DockerImageSource {
* The directory containing the Docker image build instructions.
*
* This path is relative to the asset manifest location.
*
* @default - Exactly one of `directory` and `executable` is required
*/
readonly directory?: string;

/**
* A command-line executable that returns the name of a local
* Docker image on stdout after being run.
*
* @default - Exactly one of `directory` and `executable` is required
*/
readonly directory: string;
readonly executable?: string[];

/**
* The name of the file with build instructions
*
* Only allowed when `directory` is set.
*
* @default "Dockerfile"
*/
readonly dockerFile?: string;

/**
* Target build stage in a Dockerfile with multiple build stages
*
* Only allowed when `directory` is set.
*
* @default - The last stage in the Dockerfile
*/
readonly dockerBuildTarget?: string;

/**
* Additional build arguments
*
* Only allowed when `directory` is set.
*
* @default - No additional build arguments
*/
readonly dockerBuildArgs?: { [name: string]: string };
Expand Down
15 changes: 13 additions & 2 deletions packages/@aws-cdk/cloud-assembly-schema/lib/assets/file-asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,27 @@ export enum FileAssetPackaging {
* Describe the source of a file asset
*/
export interface FileSource {
/**
* External command which will produce the file asset to upload.
*
* @default - Exactly one of `executable` and `path` is required.
*/
readonly executable?: string[];

/**
* The filesystem object to upload
*
* This path is relative to the asset manifest location.
*
* @default - Exactly one of `executable` and `path` is required.
*/
readonly path: string;
readonly path?: string;

/**
* Packaging method
*
* Only allowed when `path` is specified.
*
* @default FILE
*/
readonly packaging?: FileAssetPackaging;
Expand All @@ -62,4 +73,4 @@ export interface FileDestination extends AwsDestination {
* The destination object key
*/
readonly objectKey: string;
}
}
Loading

0 comments on commit e2f29c9

Please sign in to comment.