From 5c4fea5c7b13a354586adf49b9bc7c2ec689cd01 Mon Sep 17 00:00:00 2001 From: Barun Ray Date: Wed, 20 May 2020 22:42:27 +0530 Subject: [PATCH] feat(codeguruprofiler): setup L2 construct to create profiler group and setup functions to add publish/read policies to IGrantable --- .../@aws-cdk/aws-codeguruprofiler/README.md | 4 +- .../aws-codeguruprofiler/lib/index.ts | 1 + .../lib/profiling-group-base.ts | 81 ------------ .../lib/profiling-group.ts | 125 +++++++++++++++++- .../aws-codeguruprofiler/package.json | 3 +- .../test/integ.profiler-group.expected.json | 2 +- .../test/integ.profiler-group.ts | 6 +- .../test/profiling-group.test.ts | 2 +- 8 files changed, 129 insertions(+), 95 deletions(-) delete mode 100644 packages/@aws-cdk/aws-codeguruprofiler/lib/profiling-group-base.ts diff --git a/packages/@aws-cdk/aws-codeguruprofiler/README.md b/packages/@aws-cdk/aws-codeguruprofiler/README.md index a314e34faaca4..5fcb3137d296b 100644 --- a/packages/@aws-cdk/aws-codeguruprofiler/README.md +++ b/packages/@aws-cdk/aws-codeguruprofiler/README.md @@ -29,8 +29,6 @@ const publishAppRole = new Role(stack, 'PublishAppRole', { assumedBy: new AccountRootPrincipal(), }); -const profilingGroup = new ProfilingGroup(stack, 'MyProfilingGroup', { - profilingGroupName: 'MyAwesomeProfilingGroup', -}); +const profilingGroup = new ProfilingGroup(stack, 'MyProfilingGroup'); profilingGroup.grantPublish(publishAppRole); ``` diff --git a/packages/@aws-cdk/aws-codeguruprofiler/lib/index.ts b/packages/@aws-cdk/aws-codeguruprofiler/lib/index.ts index 1dca345aee39a..6ee79ba3c2171 100644 --- a/packages/@aws-cdk/aws-codeguruprofiler/lib/index.ts +++ b/packages/@aws-cdk/aws-codeguruprofiler/lib/index.ts @@ -1,2 +1,3 @@ // AWS::CodeGuruProfiler CloudFormation Resources: export * from './codeguruprofiler.generated'; +export * from './profiling-group'; diff --git a/packages/@aws-cdk/aws-codeguruprofiler/lib/profiling-group-base.ts b/packages/@aws-cdk/aws-codeguruprofiler/lib/profiling-group-base.ts deleted file mode 100644 index 3f323bfcd81fe..0000000000000 --- a/packages/@aws-cdk/aws-codeguruprofiler/lib/profiling-group-base.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { Grant, IGrantable } from '@aws-cdk/aws-iam'; -import { IResource, Resource } from '@aws-cdk/core'; - -export interface IProfilingGroup extends IResource { - - /** - * A name for the profiling group. - */ - readonly profilingGroupName: string; - - /** - * Grant access to publish profiling information to the Profiling Group to the given identity. - * - * This will grant the following permissions: - * - * - codeguru-profiler:ConfigureAgent - * - codeguru-profiler:PostAgentProfile - * - * @param grantee Principal to grant publish rights to - */ - grantPublish(grantee: IGrantable): void; - - /** - * Grant access to read profiling information from the Profiling Group to the given identity. - * - * This will grant the following permissions: - * - * - codeguru-profiler:GetProfile - * - codeguru-profiler:DescribeProfilingGroup - * - * @param grantee Principal to grant read rights to - */ - grantRead(grantee: IGrantable): void; - -} - -export abstract class ProfilingGroupBase extends Resource implements IProfilingGroup { - - public abstract readonly profilingGroupName: string; - - public abstract readonly profilingGroupArn: string; - - /** - * Grant access to publish profiling information to the Profiling Group to the given identity. - * - * This will grant the following permissions: - * - * - codeguru-profiler:ConfigureAgent - * - codeguru-profiler:PostAgentProfile - * - * @param grantee Principal to grant publish rights to - */ - public grantPublish(grantee: IGrantable) { - // https://docs.aws.amazon.com/codeguru/latest/profiler-ug/security-iam.html#security-iam-access-control - return Grant.addToPrincipal({ - grantee, - actions: ['codeguru-profiler:ConfigureAgent', 'codeguru-profiler:PostAgentProfile'], - resourceArns: [this.profilingGroupArn], - }); - } - - /** - * Grant access to read profiling information from the Profiling Group to the given identity. - * - * This will grant the following permissions: - * - * - codeguru-profiler:GetProfile - * - codeguru-profiler:DescribeProfilingGroup - * - * @param grantee Principal to grant read rights to - */ - public grantRead(grantee: IGrantable) { - // https://docs.aws.amazon.com/codeguru/latest/profiler-ug/security-iam.html#security-iam-access-control - return Grant.addToPrincipal({ - grantee, - actions: ['codeguru-profiler:GetProfile', 'codeguru-profiler:DescribeProfilingGroup'], - resourceArns: [this.profilingGroupArn], - }); - } - -} diff --git a/packages/@aws-cdk/aws-codeguruprofiler/lib/profiling-group.ts b/packages/@aws-cdk/aws-codeguruprofiler/lib/profiling-group.ts index 8ab863fe61612..f4d356e093204 100644 --- a/packages/@aws-cdk/aws-codeguruprofiler/lib/profiling-group.ts +++ b/packages/@aws-cdk/aws-codeguruprofiler/lib/profiling-group.ts @@ -1,6 +1,90 @@ -import { Construct, Lazy, Stack } from '@aws-cdk/core'; +import { Grant, IGrantable } from '@aws-cdk/aws-iam'; +import { Construct, IResource, Lazy, Resource, Stack } from '@aws-cdk/core'; import { CfnProfilingGroup } from './codeguruprofiler.generated'; -import { IProfilingGroup, ProfilingGroupBase } from './profiling-group-base'; + +/** + * IResource represents a Profiling Group. + */ +export interface IProfilingGroup extends IResource { + + /** + * A name for the profiling group. + * + * @attribute + */ + readonly profilingGroupName: string; + + /** + * Grant access to publish profiling information to the Profiling Group to the given identity. + * + * This will grant the following permissions: + * + * - codeguru-profiler:ConfigureAgent + * - codeguru-profiler:PostAgentProfile + * + * @param grantee Principal to grant publish rights to + */ + grantPublish(grantee: IGrantable): Grant; + + /** + * Grant access to read profiling information from the Profiling Group to the given identity. + * + * This will grant the following permissions: + * + * - codeguru-profiler:GetProfile + * - codeguru-profiler:DescribeProfilingGroup + * + * @param grantee Principal to grant read rights to + */ + grantRead(grantee: IGrantable): Grant; + +} + +abstract class ProfilingGroupBase extends Resource implements IProfilingGroup { + + public abstract readonly profilingGroupName: string; + + public abstract readonly profilingGroupArn: string; + + /** + * Grant access to publish profiling information to the Profiling Group to the given identity. + * + * This will grant the following permissions: + * + * - codeguru-profiler:ConfigureAgent + * - codeguru-profiler:PostAgentProfile + * + * @param grantee Principal to grant publish rights to + */ + public grantPublish(grantee: IGrantable) { + // https://docs.aws.amazon.com/codeguru/latest/profiler-ug/security-iam.html#security-iam-access-control + return Grant.addToPrincipal({ + grantee, + actions: ['codeguru-profiler:ConfigureAgent', 'codeguru-profiler:PostAgentProfile'], + resourceArns: [this.profilingGroupArn], + }); + } + + /** + * Grant access to read profiling information from the Profiling Group to the given identity. + * + * This will grant the following permissions: + * + * - codeguru-profiler:GetProfile + * - codeguru-profiler:DescribeProfilingGroup + * + * @param grantee Principal to grant read rights to + */ + public grantRead(grantee: IGrantable) { + // https://docs.aws.amazon.com/codeguru/latest/profiler-ug/security-iam.html#security-iam-access-control + return Grant.addToPrincipal({ + grantee, + actions: ['codeguru-profiler:GetProfile', 'codeguru-profiler:DescribeProfilingGroup'], + resourceArns: [this.profilingGroupArn], + }); + } + +} /** * Properties for creating a new Profiling Group. @@ -20,6 +104,13 @@ export interface ProfilingGroupProps { */ export class ProfilingGroup extends ProfilingGroupBase { + /** + * Import an existing Profiling Group provided a Profiling Group Name. + * + * @param scope The parent creating construct + * @param id The construct's name + * @param profilingGroupName Profiling Group Name + */ public static fromProfilingGroupName(scope: Construct, id: string, profilingGroupName: string): IProfilingGroup { const stack = Stack.of(scope); @@ -30,6 +121,13 @@ export class ProfilingGroup extends ProfilingGroupBase { })); } + /** + * Import an existing Profiling Group provided an ARN. + * + * @param scope The parent creating construct + * @param id The construct's name + * @param profilingGroupArn Profiling Group ARN + */ public static fromProfilingGroupArn(scope: Construct, id: string, profilingGroupArn: string): IProfilingGroup { class Import extends ProfilingGroupBase { public readonly profilingGroupName = Stack.of(scope).parseArn(profilingGroupArn).resource; @@ -39,12 +137,23 @@ export class ProfilingGroup extends ProfilingGroupBase { return new Import(scope, id); } + /** + * The name of the Profiling Group. + * + * @attribute + */ public readonly profilingGroupName: string; + + /** + * The ARN of the Profiling Group. + * + * @attribute + */ public readonly profilingGroupArn: string; - constructor(scope: Construct, id: string, props: ProfilingGroupProps) { + constructor(scope: Construct, id: string, props: ProfilingGroupProps = {}) { super(scope, id, { - physicalName: props.profilingGroupName || Lazy.stringValue({ produce: () => this.node.uniqueId }), + physicalName: props.profilingGroupName ?? Lazy.stringValue({ produce: () => this.generateUniqueId() }), }); const profilingGroup = new CfnProfilingGroup(this, 'ProfilingGroup', { @@ -60,4 +169,12 @@ export class ProfilingGroup extends ProfilingGroupBase { }); } + private generateUniqueId(): string { + const name = this.node.uniqueId; + if (name.length > 240) { + return name.substring(0, 120) + name.substring(name.length - 120); + } + return name; + } + } diff --git a/packages/@aws-cdk/aws-codeguruprofiler/package.json b/packages/@aws-cdk/aws-codeguruprofiler/package.json index eb390ab251ba0..a114721c9e514 100644 --- a/packages/@aws-cdk/aws-codeguruprofiler/package.json +++ b/packages/@aws-cdk/aws-codeguruprofiler/package.json @@ -77,7 +77,8 @@ }, "peerDependencies": { "@aws-cdk/core": "0.0.0", - "@aws-cdk/aws-iam": "0.0.0" + "@aws-cdk/aws-iam": "0.0.0", + "constructs": "^3.0.2" }, "engines": { "node": ">= 10.13.0 <13 || >=13.7.0" diff --git a/packages/@aws-cdk/aws-codeguruprofiler/test/integ.profiler-group.expected.json b/packages/@aws-cdk/aws-codeguruprofiler/test/integ.profiler-group.expected.json index 1e5adb63e01d5..8ea1221f6bbe8 100644 --- a/packages/@aws-cdk/aws-codeguruprofiler/test/integ.profiler-group.expected.json +++ b/packages/@aws-cdk/aws-codeguruprofiler/test/integ.profiler-group.expected.json @@ -3,7 +3,7 @@ "MyProfilingGroup829F0507": { "Type": "AWS::CodeGuruProfiler::ProfilingGroup", "Properties": { - "ProfilingGroupName": "MyAwesomeProfilingGroup" + "ProfilingGroupName": "ProfilerGroupIntegrationTestMyProfilingGroup81DA69A3" } }, "PublishAppRole9FEBD682": { diff --git a/packages/@aws-cdk/aws-codeguruprofiler/test/integ.profiler-group.ts b/packages/@aws-cdk/aws-codeguruprofiler/test/integ.profiler-group.ts index c1a7c30b8dd1a..d947e85e823a4 100644 --- a/packages/@aws-cdk/aws-codeguruprofiler/test/integ.profiler-group.ts +++ b/packages/@aws-cdk/aws-codeguruprofiler/test/integ.profiler-group.ts @@ -1,14 +1,12 @@ import { AccountRootPrincipal, Role } from '@aws-cdk/aws-iam'; import { App, Stack, StackProps } from '@aws-cdk/core'; -import { ProfilingGroup } from '../lib/profiling-group'; +import { ProfilingGroup } from '../lib'; class ProfilerGroupIntegrationTest extends Stack { constructor(scope: App, id: string, props?: StackProps) { super(scope, id, props); - const profilingGroup = new ProfilingGroup(this, 'MyProfilingGroup', { - profilingGroupName: 'MyAwesomeProfilingGroup', - }); + const profilingGroup = new ProfilingGroup(this, 'MyProfilingGroup'); const publishAppRole = new Role(this, 'PublishAppRole', { assumedBy: new AccountRootPrincipal(), diff --git a/packages/@aws-cdk/aws-codeguruprofiler/test/profiling-group.test.ts b/packages/@aws-cdk/aws-codeguruprofiler/test/profiling-group.test.ts index 1d1affe0ced56..e31bba2dcf002 100644 --- a/packages/@aws-cdk/aws-codeguruprofiler/test/profiling-group.test.ts +++ b/packages/@aws-cdk/aws-codeguruprofiler/test/profiling-group.test.ts @@ -1,7 +1,7 @@ import { expect } from '@aws-cdk/assert'; import { AccountRootPrincipal, Role } from '@aws-cdk/aws-iam'; import { Stack } from '@aws-cdk/core'; -import { ProfilingGroup } from '../lib/profiling-group'; +import { ProfilingGroup } from '../lib'; // tslint:disable:object-literal-key-quotes