Skip to content

Commit

Permalink
fix(aws-logs): add export()/import() capabilities (#630)
Browse files Browse the repository at this point in the history
LogGroups and LogStreams can now be exported and imported.

ALSO IN THIS COMMIT

- All exports() for other resources would run afoul of
  ClassCastException in Java. Wrap all `FnImportValue`s in the right
  type to avoid this.
- The addition of some convenience methods to the `Arn` class flushed
  out a number of places where we were using some other `Token`-derived
  value in places where `Arn`s were expected.
  • Loading branch information
rix0rrr authored Sep 3, 2018
1 parent 6b793e9 commit c3372b7
Show file tree
Hide file tree
Showing 27 changed files with 237 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export abstract class CertificateRef extends Construct {
*/
public export(): CertificateRefProps {
return {
certificateArn: new Output(this, 'Arn', { value: this.certificateArn }).makeImportValue()
certificateArn: new CertificateArn(new Output(this, 'Arn', { value: this.certificateArn }).makeImportValue())
};
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-cloudtrail/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,11 @@ export class CloudTrail extends cdk.Construct {
const logGroup = new logs.cloudformation.LogGroupResource(this, "LogGroup", {
retentionInDays: props.cloudWatchLogsRetentionTimeDays || LogRetention.OneYear
});
this.cloudWatchLogsGroupArn = logGroup.ref;
this.cloudWatchLogsGroupArn = logGroup.logGroupArn;

const logsRole = new iam.Role(this, 'LogsRole', {assumedBy: new cdk.ServicePrincipal(cloudTrailPrincipal) });

const streamArn = new cdk.FnConcat(this.cloudWatchLogsGroupArn, ":log-stream:*");
const streamArn = new cdk.Arn(new cdk.FnConcat(this.cloudWatchLogsGroupArn, ":log-stream:*"));
logsRole.addToPolicy(new cdk.PolicyStatement()
.addActions("logs:PutLogEvents", "logs:CreateLogStream")
.addResource(streamArn));
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-codebuild/lib/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export abstract class ProjectRef extends cdk.Construct implements events.IEventR
*/
public export(): ProjectRefProps {
return {
projectName: new cdk.Output(this, 'ProjectName', { value: this.projectName }).makeImportValue(),
projectName: new ProjectName(new cdk.Output(this, 'ProjectName', { value: this.projectName }).makeImportValue()),
};
}

Expand Down Expand Up @@ -482,7 +482,7 @@ export class Project extends ProjectRef {
resourceName: new cdk.FnConcat('/aws/codebuild/', this.projectName),
});

const logGroupStarArn = new cdk.FnConcat(logGroupArn, ':*');
const logGroupStarArn = new cdk.Arn(new cdk.FnConcat(logGroupArn, ':*'));

const p = new cdk.PolicyStatement();
p.allow();
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-codecommit/lib/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export abstract class RepositoryRef extends cdk.Construct {
*/
public export(): RepositoryRefProps {
return {
repositoryName: new cdk.Output(this, 'RepositoryName', { value: this.repositoryName }).makeImportValue(),
repositoryName: new RepositoryName(new cdk.Output(this, 'RepositoryName', { value: this.repositoryName }).makeImportValue()),
};
}

Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-ec2/lib/security-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export abstract class SecurityGroupRef extends Construct implements ISecurityGro
*/
public export(): SecurityGroupRefProps {
return {
securityGroupId: new Output(this, 'SecurityGroupId', { value: this.securityGroupId }).makeImportValue()
securityGroupId: new SecurityGroupId(new Output(this, 'SecurityGroupId', { value: this.securityGroupId }).makeImportValue())
};
}

Expand Down
8 changes: 5 additions & 3 deletions packages/@aws-cdk/aws-ec2/lib/vpc-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,14 @@ export abstract class VpcNetworkRef extends Construct implements IDependable {
* Export this VPC from the stack
*/
public export(): VpcNetworkRefProps {
// tslint:disable:max-line-length
return {
vpcId: new Output(this, 'VpcId', { value: this.vpcId }).makeImportValue(),
vpcId: new VPCId(new Output(this, 'VpcId', { value: this.vpcId }).makeImportValue()),
availabilityZones: this.publicSubnets.map(s => s.availabilityZone),
publicSubnetIds: new StringListOutput(this, 'PublicSubnetIDs', { values: this.publicSubnets.map(s => s.subnetId) }).makeImportValues(),
privateSubnetIds: new StringListOutput(this, 'PrivateSubnetIDs', { values: this.privateSubnets.map(s => s.subnetId) }).makeImportValues(),
publicSubnetIds: new StringListOutput(this, 'PublicSubnetIDs', { values: this.publicSubnets.map(s => s.subnetId) }).makeImportValues().map(x => new SubnetId(x)),
privateSubnetIds: new StringListOutput(this, 'PrivateSubnetIDs', { values: this.privateSubnets.map(s => s.subnetId) }).makeImportValues().map(x => new SubnetId(x)),
};
// tslint:enable:max-line-length
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-events/lib/rule-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export abstract class EventRuleRef extends Construct {
*/
public export(): EventRuleRefProps {
return {
eventRuleArn: new Output(this, 'RuleArn', { value: this.ruleArn }).makeImportValue()
eventRuleArn: new RuleArn(new Output(this, 'RuleArn', { value: this.ruleArn }).makeImportValue())
};
}
}
Expand Down
17 changes: 6 additions & 11 deletions packages/@aws-cdk/aws-kinesis/lib/stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,10 @@ export abstract class StreamRef extends cdk.Construct implements logs.ILogSubscr
* Exports this stream from the stack.
*/
public export(): StreamRefProps {
const streamArn = new cdk.Output(this, 'StreamArn', { value: this.streamArn }).makeImportValue();
if (this.encryptionKey) {
return {
streamArn,
encryptionKey: this.encryptionKey.export()
};
} else {
return { streamArn };
}
return {
streamArn: new StreamArn(new cdk.Output(this, 'StreamArn', { value: this.streamArn }).makeImportValue()),
encryptionKey: this.encryptionKey ? this.encryptionKey.export() : undefined,
};
}

/**
Expand Down Expand Up @@ -170,7 +165,7 @@ export abstract class StreamRef extends cdk.Construct implements logs.ILogSubscr
);
}

public logSubscriptionDestination(sourceLogGroup: logs.LogGroup): logs.LogSubscriptionDestination {
public logSubscriptionDestination(sourceLogGroup: logs.LogGroupRef): logs.LogSubscriptionDestination {
// Following example from https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SubscriptionFilters.html#DestinationKinesisExample
if (!this.cloudWatchLogsRole) {
// Create a role to be assumed by CWL that can write to this stream and pass itself.
Expand Down Expand Up @@ -200,7 +195,7 @@ export abstract class StreamRef extends cdk.Construct implements logs.ILogSubscr
/**
* Generate a CloudWatch Logs Destination and return the properties in the form o a subscription destination
*/
private crossAccountLogSubscriptionDestination(sourceLogGroup: logs.LogGroup): logs.LogSubscriptionDestination {
private crossAccountLogSubscriptionDestination(sourceLogGroup: logs.LogGroupRef): logs.LogSubscriptionDestination {
const sourceStack = cdk.Stack.find(sourceLogGroup);
const thisStack = cdk.Stack.find(this);

Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-kms/lib/key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export abstract class EncryptionKeyRef extends Construct {
*/
public export(): EncryptionKeyRefProps {
return {
keyArn: new Output(this, 'KeyArn').makeImportValue()
keyArn: new KeyArn(new Output(this, 'KeyArn').makeImportValue())
};
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-kms/test/integ.key.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { App, AwsAccountId, PolicyStatement, Stack } from '@aws-cdk/cdk';
import { App, Arn, AwsAccountId, PolicyStatement, Stack } from '@aws-cdk/cdk';
import { EncryptionKey } from '../lib';

const app = new App(process.argv);
Expand All @@ -10,7 +10,7 @@ const key = new EncryptionKey(stack, 'MyKey');
key.addToResourcePolicy(new PolicyStatement()
.addAllResources()
.addAction('kms:encrypt')
.addAwsPrincipal(new AwsAccountId()));
.addAwsPrincipal(new Arn(new AwsAccountId())));

key.addAlias('alias/bar');

Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-lambda/lib/lambda-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ export abstract class FunctionRef extends cdk.Construct
return this.metric('Throttles', { statistic: 'sum', ...props });
}

public logSubscriptionDestination(sourceLogGroup: logs.LogGroup): logs.LogSubscriptionDestination {
public logSubscriptionDestination(sourceLogGroup: logs.LogGroupRef): logs.LogSubscriptionDestination {
const arn = sourceLogGroup.logGroupArn;

if (this.logSubscriptionDestinationPolicyAddedFor.indexOf(arn) === -1) {
Expand All @@ -260,7 +260,7 @@ export abstract class FunctionRef extends cdk.Construct
*/
public export(): FunctionRefProps {
return {
functionArn: new cdk.Output(this, 'FunctionArn', { value: this.functionArn }).makeImportValue(),
functionArn: new FunctionArn(new cdk.Output(this, 'FunctionArn', { value: this.functionArn }).makeImportValue()),
};
}

Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-logs/lib/cross-account-destination.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import iam = require('@aws-cdk/aws-iam');
import cdk = require('@aws-cdk/cdk');
import { LogGroup } from './log-group';
import { LogGroupRef } from './log-group';
import { cloudformation, DestinationArn, DestinationName } from './logs.generated';
import { ILogSubscriptionDestination, LogSubscriptionDestination } from './subscription-filter';

Expand Down Expand Up @@ -78,7 +78,7 @@ export class CrossAccountDestination extends cdk.Construct implements ILogSubscr
this.policyDocument.addStatement(statement);
}

public logSubscriptionDestination(_sourceLogGroup: LogGroup): LogSubscriptionDestination {
public logSubscriptionDestination(_sourceLogGroup: LogGroupRef): LogSubscriptionDestination {
return { arn: this.destinationArn };
}

Expand Down
134 changes: 97 additions & 37 deletions packages/@aws-cdk/aws-logs/lib/log-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,87 @@ import { IFilterPattern } from './pattern';
import { ILogSubscriptionDestination, SubscriptionFilter } from './subscription-filter';

/**
* Properties for a new LogGroup
* Properties for importing a LogGroup
*/
export interface LogGroupRefProps {
logGroupArn: LogGroupArn;
}

/**
* An CloudWatch Log Group
*/
export abstract class LogGroupRef extends cdk.Construct {
/**
* Import an existing LogGroup
*/
public static import(parent: cdk.Construct, id: string, props: LogGroupRefProps): LogGroupRef {
return new ImportedLogGroup(parent, id, props);
}

/**
* The ARN of this log group
*/
public abstract readonly logGroupArn: LogGroupArn;

/**
* The name of this log group
*/
public abstract readonly logGroupName: LogGroupName;

/**
* Create a new Log Stream for this Log Group
*
* @param parent Parent construct
* @param id Unique identifier for the construct in its parent
* @param props Properties for creating the LogStream
*/
public newStream(parent: cdk.Construct, id: string, props: NewLogStreamProps = {}): LogStream {
return new LogStream(parent, id, {
logGroup: this,
...props
});
}

/**
* Create a new Subscription Filter on this Log Group
*
* @param parent Parent construct
* @param id Unique identifier for the construct in its parent
* @param props Properties for creating the SubscriptionFilter
*/
public newSubscriptionFilter(parent: cdk.Construct, id: string, props: NewSubscriptionFilterProps): SubscriptionFilter {
return new SubscriptionFilter(parent, id, {
logGroup: this,
...props
});
}

/**
* Create a new Metric Filter on this Log Group
*
* @param parent Parent construct
* @param id Unique identifier for the construct in its parent
* @param props Properties for creating the MetricFilter
*/
public newMetricFilter(parent: cdk.Construct, id: string, props: NewMetricFilterProps): MetricFilter {
return new MetricFilter(parent, id, {
logGroup: this,
...props
});
}

/**
* Export this LogGroup
*/
public export(): LogGroupRefProps {
return {
logGroupArn: new LogGroupArn(new cdk.Output(this, 'LogGroupArn', { value: this.logGroupArn }).makeImportValue())
};
}
}

/**
* Properties for a LogGroup
*/
export interface LogGroupProps {
/**
Expand Down Expand Up @@ -39,9 +119,9 @@ export interface LogGroupProps {
}

/**
* A new CloudWatch Log Group
* Define a CloudWatch Log Group
*/
export class LogGroup extends cdk.Construct {
export class LogGroup extends LogGroupRef {
/**
* The ARN of this log group
*/
Expand Down Expand Up @@ -75,47 +155,27 @@ export class LogGroup extends cdk.Construct {
this.logGroupArn = resource.logGroupArn;
this.logGroupName = resource.ref;
}
}

/**
* An imported CloudWatch Log Group
*/
class ImportedLogGroup extends LogGroupRef {
/**
* Create a new Log Stream for this Log Group
*
* @param parent Parent construct
* @param id Unique identifier for the construct in its parent
* @param props Properties for creating the LogStream
* The ARN of this log group
*/
public newStream(parent: cdk.Construct, id: string, props: NewLogStreamProps = {}): LogStream {
return new LogStream(parent, id, {
logGroup: this,
...props
});
}
public readonly logGroupArn: LogGroupArn;

/**
* Create a new Subscription Filter on this Log Group
*
* @param parent Parent construct
* @param id Unique identifier for the construct in its parent
* @param props Properties for creating the SubscriptionFilter
* The name of this log group
*/
public newSubscriptionFilter(parent: cdk.Construct, id: string, props: NewSubscriptionFilterProps): SubscriptionFilter {
return new SubscriptionFilter(parent, id, {
logGroup: this,
...props
});
}
public readonly logGroupName: LogGroupName;

/**
* Create a new Metric Filter on this Log Group
*
* @param parent Parent construct
* @param id Unique identifier for the construct in its parent
* @param props Properties for creating the MetricFilter
*/
public newMetricFilter(parent: cdk.Construct, id: string, props: NewMetricFilterProps): MetricFilter {
return new MetricFilter(parent, id, {
logGroup: this,
...props
});
constructor(parent: cdk.Construct, id: string, props: LogGroupRefProps) {
super(parent, id);

this.logGroupArn = props.logGroupArn;
this.logGroupName = new LogGroupName(props.logGroupArn.resourceNameComponent(':'));
}
}

Expand Down
Loading

0 comments on commit c3372b7

Please sign in to comment.