/
report-group.ts
154 lines (137 loc) · 4.45 KB
/
report-group.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import * as iam from '@aws-cdk/aws-iam';
import * as s3 from '@aws-cdk/aws-s3';
import * as cdk from '@aws-cdk/core';
import { Construct } from 'constructs';
import { CfnReportGroup } from './codebuild.generated';
import { renderReportGroupArn, reportGroupArnComponents } from './report-group-utils';
/**
* The interface representing the ReportGroup resource -
* either an existing one, imported using the
* {@link ReportGroup.fromReportGroupName} method,
* or a new one, created with the {@link ReportGroup} class.
*/
export interface IReportGroup extends cdk.IResource {
/**
* The ARN of the ReportGroup.
*
* @attribute
*/
readonly reportGroupArn: string;
/**
* The name of the ReportGroup.
*
* @attribute
*/
readonly reportGroupName: string;
/**
* Grants the given entity permissions to write
* (that is, upload reports to)
* this report group.
*/
grantWrite(identity: iam.IGrantable): iam.Grant;
}
abstract class ReportGroupBase extends cdk.Resource implements IReportGroup {
public abstract readonly reportGroupArn: string;
public abstract readonly reportGroupName: string;
protected abstract readonly exportBucket?: s3.IBucket;
public grantWrite(identity: iam.IGrantable): iam.Grant {
const ret = iam.Grant.addToPrincipal({
grantee: identity,
actions: [
'codebuild:CreateReport',
'codebuild:UpdateReport',
'codebuild:BatchPutTestCases',
],
resourceArns: [this.reportGroupArn],
});
if (this.exportBucket) {
this.exportBucket.grantWrite(identity);
}
return ret;
}
}
/**
* Construction properties for {@link ReportGroup}.
*/
export interface ReportGroupProps {
/**
* The physical name of the report group.
*
* @default - CloudFormation-generated name
*/
readonly reportGroupName?: string;
/**
* An optional S3 bucket to export the reports to.
*
* @default - the reports will not be exported
*/
readonly exportBucket?: s3.IBucket;
/**
* Whether to output the report files into the export bucket as-is,
* or create a ZIP from them before doing the export.
* Ignored if {@link exportBucket} has not been provided.
*
* @default - false (the files will not be ZIPped)
*/
readonly zipExport?: boolean;
/**
* What to do when this resource is deleted from a stack.
* As CodeBuild does not allow deleting a ResourceGroup that has reports inside of it,
* this is set to retain the resource by default.
*
* @default RemovalPolicy.RETAIN
*/
readonly removalPolicy?: cdk.RemovalPolicy;
}
/**
* The ReportGroup resource class.
*/
export class ReportGroup extends ReportGroupBase {
/**
* Reference an existing ReportGroup,
* defined outside of the CDK code,
* by name.
*/
public static fromReportGroupName(scope: Construct, id: string, reportGroupName: string): IReportGroup {
class Import extends ReportGroupBase {
public readonly reportGroupName = reportGroupName;
public readonly reportGroupArn = renderReportGroupArn(scope, reportGroupName);
protected readonly exportBucket = undefined;
}
return new Import(scope, id);
}
public readonly reportGroupArn: string;
public readonly reportGroupName: string;
protected readonly exportBucket?: s3.IBucket;
constructor(scope: Construct, id: string, props: ReportGroupProps = {}) {
super(scope, id, {
physicalName: props.reportGroupName,
});
const resource = new CfnReportGroup(this, 'Resource', {
type: 'TEST',
exportConfig: {
exportConfigType: props.exportBucket ? 'S3' : 'NO_EXPORT',
s3Destination: props.exportBucket
? {
bucket: props.exportBucket.bucketName,
encryptionDisabled: props.exportBucket.encryptionKey ? false : undefined,
encryptionKey: props.exportBucket.encryptionKey?.keyArn,
packaging: props.zipExport ? 'ZIP' : undefined,
}
: undefined,
},
name: props.reportGroupName,
});
resource.applyRemovalPolicy(props.removalPolicy, {
default: cdk.RemovalPolicy.RETAIN,
});
this.reportGroupArn = this.getResourceArnAttribute(resource.attrArn,
reportGroupArnComponents(this.physicalName));
this.reportGroupName = this.getResourceNameAttribute(
// there is no separate name attribute,
// so use Fn::Select + Fn::Split to make one
cdk.Fn.select(1, cdk.Fn.split('/', resource.ref)),
);
this.exportBucket = props.exportBucket;
}
}