@fjall/components-infrastructure 0.79.3 → 0.80.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/app.d.ts +39 -2
- package/dist/lib/app.js +85 -4
- package/dist/lib/aspects/resourceInventory.d.ts +41 -0
- package/dist/lib/aspects/resourceInventory.js +56 -0
- package/dist/lib/config/audit.d.ts +18 -0
- package/dist/lib/config/audit.js +22 -0
- package/dist/lib/config/aws/accountId.js +3 -3
- package/dist/lib/config/aws/ecrDefaultImage.js +7 -7
- package/dist/lib/config/aws/identityCenter.js +7 -8
- package/dist/lib/config/aws/identityCenterGroupMembership.js +6 -6
- package/dist/lib/config/aws/ipam.js +3 -3
- package/dist/lib/config/aws/ipamPoolId.js +4 -4
- package/dist/lib/config/aws/organisation.js +2 -3
- package/dist/lib/config/aws/organisationId.js +4 -4
- package/dist/lib/patterns/aws/auditRole.d.ts +44 -0
- package/dist/lib/patterns/aws/auditRole.js +58 -0
- package/dist/lib/patterns/aws/buildkite.js +12 -12
- package/dist/lib/patterns/aws/cdn.d.ts +133 -0
- package/dist/lib/patterns/aws/cdn.js +216 -0
- package/dist/lib/patterns/aws/compute.d.ts +32 -13
- package/dist/lib/patterns/aws/compute.js +24 -14
- package/dist/lib/patterns/aws/database.d.ts +2 -1
- package/dist/lib/patterns/aws/database.js +7 -2
- package/dist/lib/patterns/aws/dynamodb.d.ts +66 -0
- package/dist/lib/patterns/aws/dynamodb.js +106 -0
- package/dist/lib/patterns/aws/hostedZone.js +1 -1
- package/dist/lib/patterns/aws/index.d.ts +1 -0
- package/dist/lib/patterns/aws/index.js +2 -1
- package/dist/lib/patterns/aws/loadBalancer.d.ts +163 -0
- package/dist/lib/patterns/aws/loadBalancer.js +278 -0
- package/dist/lib/patterns/aws/managedAccount.js +3 -4
- package/dist/lib/patterns/aws/queue.d.ts +61 -0
- package/dist/lib/patterns/aws/queue.js +103 -0
- package/dist/lib/patterns/aws/storage.js +3 -2
- package/dist/lib/patterns/aws/subdomainHostedZone.js +2 -2
- package/dist/lib/resources/aws/audit/auditRole.d.ts +32 -0
- package/dist/lib/resources/aws/audit/auditRole.js +44 -0
- package/dist/lib/resources/aws/backup/backupPlan.js +3 -4
- package/dist/lib/resources/aws/backup/backupVault.js +3 -4
- package/dist/lib/resources/aws/base/awsStack.js +1 -2
- package/dist/lib/resources/aws/cdn/cloudFront.d.ts +65 -0
- package/dist/lib/resources/aws/cdn/cloudFront.js +135 -0
- package/dist/lib/resources/aws/cdn/index.d.ts +1 -0
- package/dist/lib/resources/aws/cdn/index.js +18 -0
- package/dist/lib/resources/aws/compute/capacityProviderDrainWaiter.d.ts +20 -0
- package/dist/lib/resources/aws/compute/capacityProviderDrainWaiter.js +180 -0
- package/dist/lib/resources/aws/compute/ecs.d.ts +65 -11
- package/dist/lib/resources/aws/compute/ecs.js +293 -124
- package/dist/lib/resources/aws/compute/ecsFreeTier.d.ts +1 -2
- package/dist/lib/resources/aws/compute/ecsFreeTier.js +1 -4
- package/dist/lib/resources/aws/compute/ecsSpot.d.ts +1 -2
- package/dist/lib/resources/aws/compute/ecsSpot.js +1 -4
- package/dist/lib/resources/aws/compute/lambda.d.ts +10 -1
- package/dist/lib/resources/aws/compute/lambda.js +71 -4
- package/dist/lib/resources/aws/database/database.js +1 -1
- package/dist/lib/resources/aws/database/dynamodb.d.ts +70 -0
- package/dist/lib/resources/aws/database/dynamodb.js +170 -0
- package/dist/lib/resources/aws/database/rdsAurora.js +5 -5
- package/dist/lib/resources/aws/database/rdsAuroraGlobal.js +7 -7
- package/dist/lib/resources/aws/database/rdsDeletionWaiter.d.ts +33 -0
- package/dist/lib/resources/aws/database/rdsDeletionWaiter.js +74 -0
- package/dist/lib/resources/aws/database/rdsInstance.js +3 -3
- package/dist/lib/resources/aws/iam/identityCenter/assignment.js +2 -2
- package/dist/lib/resources/aws/iam/identityCenter/attachManagedPolicy.js +1 -1
- package/dist/lib/resources/aws/iam/identityCenter/group.js +1 -1
- package/dist/lib/resources/aws/iam/identityCenter/permissionSet.js +1 -1
- package/dist/lib/resources/aws/logging/cloudTrail.js +1 -1
- package/dist/lib/resources/aws/messaging/index.d.ts +1 -0
- package/dist/lib/resources/aws/messaging/index.js +18 -0
- package/dist/lib/resources/aws/messaging/sqs.d.ts +65 -0
- package/dist/lib/resources/aws/messaging/sqs.js +195 -0
- package/dist/lib/resources/aws/monitoring/monitoringRole.js +2 -3
- package/dist/lib/resources/aws/networking/ipamPool.js +1 -1
- package/dist/lib/resources/aws/networking/vpc.d.ts +1 -0
- package/dist/lib/resources/aws/networking/vpc.js +7 -3
- package/dist/lib/resources/aws/networking/vpcEndpoint.d.ts +20 -0
- package/dist/lib/resources/aws/networking/vpcEndpoint.js +59 -0
- package/dist/lib/resources/aws/networking/vpcEndpoints.d.ts +71 -0
- package/dist/lib/resources/aws/networking/vpcEndpoints.js +125 -0
- package/dist/lib/resources/aws/secrets/secret.js +1 -1
- package/dist/lib/resources/aws/storage/ecr.d.ts +1 -2
- package/dist/lib/resources/aws/storage/ecr.js +2 -2
- package/dist/lib/resources/aws/utilities/cfnOutput.test.d.ts +1 -0
- package/dist/lib/resources/aws/utilities/cfnOutput.test.js +102 -0
- package/dist/lib/resources/aws/utilities/codeBuild.d.ts +1 -2
- package/dist/lib/resources/aws/utilities/codeBuild.js +1 -1
- package/dist/lib/resources/aws/utilities/customResource.d.ts +2 -1
- package/dist/lib/resources/aws/utilities/customResource.js +1 -1
- package/dist/lib/utils/getStackOutput.js +2 -2
- package/dist/lib/utils/sanitizeCfnKey.d.ts +5 -0
- package/dist/lib/utils/sanitizeCfnKey.js +11 -0
- package/dist/lib/utils/tagResource.d.ts +24 -0
- package/dist/lib/utils/tagResource.js +30 -0
- package/package.json +6 -5
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CdnFactory = exports.Cdn = void 0;
|
|
4
|
+
const cdn_1 = require("../../resources/aws/cdn");
|
|
5
|
+
const storage_1 = require("./storage");
|
|
6
|
+
const compute_1 = require("./compute");
|
|
7
|
+
/**
|
|
8
|
+
* Validates CDN props and logs warnings for misconfigured options.
|
|
9
|
+
*/
|
|
10
|
+
function validateCdnProps(props) {
|
|
11
|
+
// Validate certificate region warning
|
|
12
|
+
if (props.certificate && props.domainNames && props.domainNames.length > 0) {
|
|
13
|
+
console.info("[Fjall] Note: CloudFront certificates must be in us-east-1 region. " +
|
|
14
|
+
"Ensure your certificate was created in us-east-1.");
|
|
15
|
+
}
|
|
16
|
+
// Validate domain names require certificate
|
|
17
|
+
if (props.domainNames && props.domainNames.length > 0 && !props.certificate) {
|
|
18
|
+
console.warn("[Fjall] Warning: 'domainNames' provided but no 'certificate' specified. " +
|
|
19
|
+
"Custom domain names require an ACM certificate in us-east-1.");
|
|
20
|
+
}
|
|
21
|
+
// Validate ALB origin
|
|
22
|
+
if (props.originType === "alb") {
|
|
23
|
+
const albProps = props;
|
|
24
|
+
if (albProps.loadBalancer instanceof compute_1.Compute) {
|
|
25
|
+
const lb = albProps.loadBalancer.getLoadBalancer();
|
|
26
|
+
if (!lb) {
|
|
27
|
+
throw new Error("Compute resource does not have a load balancer. " +
|
|
28
|
+
"Ensure ECS compute has loadBalancer enabled for CDN origin.");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Validate smart origin
|
|
33
|
+
if (props.originType === "auto") {
|
|
34
|
+
const smartProps = props;
|
|
35
|
+
if (smartProps.origin instanceof compute_1.Compute) {
|
|
36
|
+
const computeType = smartProps.origin.getComputeType();
|
|
37
|
+
if (computeType === "ec2") {
|
|
38
|
+
throw new Error("EC2 compute type is not supported for CDN origin. " +
|
|
39
|
+
"Use ECS with load balancer or Lambda with function URL.");
|
|
40
|
+
}
|
|
41
|
+
if (computeType === "ecs" && !smartProps.origin.getLoadBalancer()) {
|
|
42
|
+
throw new Error("ECS compute must have a load balancer for CDN origin. " +
|
|
43
|
+
"Enable loadBalancer in your ECS compute configuration.");
|
|
44
|
+
}
|
|
45
|
+
if (computeType === "lambda" && !smartProps.origin.getFunctionUrl()) {
|
|
46
|
+
throw new Error("Lambda compute must have a function URL for CDN origin. " +
|
|
47
|
+
"Enable functionUrl in your Lambda compute configuration.");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* CDN wrapper class that extends CloudFrontDistribution with Fjall patterns.
|
|
54
|
+
*/
|
|
55
|
+
class Cdn extends cdn_1.CloudFrontDistribution {
|
|
56
|
+
constructor(scope, id, props) {
|
|
57
|
+
const resolvedProps = Cdn.resolveProps(props);
|
|
58
|
+
super(scope, id, resolvedProps);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Resolve ICdnProps to CloudFrontDistributionProps.
|
|
62
|
+
*/
|
|
63
|
+
static resolveProps(props) {
|
|
64
|
+
const defaultOrigin = Cdn.resolveDefaultOrigin(props);
|
|
65
|
+
return {
|
|
66
|
+
defaultOrigin,
|
|
67
|
+
defaultCachePolicy: props.cachePolicy,
|
|
68
|
+
behaviours: props.behaviours,
|
|
69
|
+
domainNames: props.domainNames,
|
|
70
|
+
certificate: props.certificate,
|
|
71
|
+
comment: props.comment,
|
|
72
|
+
enableLogging: props.enableLogging,
|
|
73
|
+
logBucket: props.logBucket
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Resolve the default origin from ICdnProps.
|
|
78
|
+
*/
|
|
79
|
+
static resolveDefaultOrigin(props) {
|
|
80
|
+
switch (props.originType) {
|
|
81
|
+
case "s3": {
|
|
82
|
+
const s3Props = props;
|
|
83
|
+
const bucket = s3Props.bucket instanceof storage_1.S3Storage
|
|
84
|
+
? s3Props.bucket.getBucket()
|
|
85
|
+
: s3Props.bucket;
|
|
86
|
+
return {
|
|
87
|
+
type: "s3",
|
|
88
|
+
bucket,
|
|
89
|
+
originPath: s3Props.originPath
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
case "alb": {
|
|
93
|
+
const albProps = props;
|
|
94
|
+
const loadBalancer = albProps.loadBalancer instanceof compute_1.Compute
|
|
95
|
+
? albProps.loadBalancer.getLoadBalancer()
|
|
96
|
+
: albProps.loadBalancer;
|
|
97
|
+
return {
|
|
98
|
+
type: "alb",
|
|
99
|
+
loadBalancer,
|
|
100
|
+
protocolPolicy: albProps.protocolPolicy
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
case "http": {
|
|
104
|
+
const httpProps = props;
|
|
105
|
+
return {
|
|
106
|
+
type: "http",
|
|
107
|
+
domainName: httpProps.domainName,
|
|
108
|
+
originPath: httpProps.originPath,
|
|
109
|
+
protocolPolicy: httpProps.protocolPolicy
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
case "auto": {
|
|
113
|
+
const smartProps = props;
|
|
114
|
+
return Cdn.detectOriginFromResource(smartProps.origin);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Auto-detect origin configuration from a Fjall resource.
|
|
120
|
+
*/
|
|
121
|
+
static detectOriginFromResource(resource) {
|
|
122
|
+
// String → HTTP origin
|
|
123
|
+
if (typeof resource === "string") {
|
|
124
|
+
return {
|
|
125
|
+
type: "http",
|
|
126
|
+
domainName: resource
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
// S3Storage → S3 origin
|
|
130
|
+
if (resource instanceof storage_1.S3Storage) {
|
|
131
|
+
return {
|
|
132
|
+
type: "s3",
|
|
133
|
+
bucket: resource.getBucket()
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
// Compute → ALB or Lambda origin
|
|
137
|
+
if (resource instanceof compute_1.Compute) {
|
|
138
|
+
const computeType = resource.getComputeType();
|
|
139
|
+
if (computeType === "ecs") {
|
|
140
|
+
const loadBalancer = resource.getLoadBalancer();
|
|
141
|
+
if (loadBalancer) {
|
|
142
|
+
return {
|
|
143
|
+
type: "alb",
|
|
144
|
+
loadBalancer
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (computeType === "lambda") {
|
|
149
|
+
const functionUrl = resource.getFunctionUrl();
|
|
150
|
+
if (functionUrl) {
|
|
151
|
+
// Lambda function URL is an HTTP origin
|
|
152
|
+
const url = new URL(functionUrl);
|
|
153
|
+
return {
|
|
154
|
+
type: "http",
|
|
155
|
+
domainName: url.hostname
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
throw new Error(`Unable to detect CDN origin from resource: ${typeof resource}. ` +
|
|
161
|
+
"Provide explicit origin configuration using originType.");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
exports.Cdn = Cdn;
|
|
165
|
+
/**
|
|
166
|
+
* Factory for creating CDN (CloudFront) distributions.
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* // S3 origin
|
|
170
|
+
* const assets = app.addStorage(StorageFactory.build("Assets", { bucketType: "private" }));
|
|
171
|
+
* app.addCdn(CdnFactory.build("AssetsCdn", {
|
|
172
|
+
* originType: "s3",
|
|
173
|
+
* bucket: assets
|
|
174
|
+
* }));
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* // ALB origin (ECS)
|
|
178
|
+
* const api = app.addCompute(ComputeFactory.build("Api", { type: "ecs", ... }));
|
|
179
|
+
* app.addCdn(CdnFactory.build("ApiCdn", {
|
|
180
|
+
* originType: "alb",
|
|
181
|
+
* loadBalancer: api
|
|
182
|
+
* }));
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* // Smart detection
|
|
186
|
+
* app.addCdn(CdnFactory.build("AppCdn", {
|
|
187
|
+
* originType: "auto",
|
|
188
|
+
* origin: assets
|
|
189
|
+
* }));
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* // Custom domain
|
|
193
|
+
* app.addCdn(CdnFactory.build("AppCdn", {
|
|
194
|
+
* originType: "s3",
|
|
195
|
+
* bucket: assets,
|
|
196
|
+
* domainNames: ["app.example.com"],
|
|
197
|
+
* certificate: myCert
|
|
198
|
+
* }));
|
|
199
|
+
*/
|
|
200
|
+
class CdnFactory {
|
|
201
|
+
/**
|
|
202
|
+
* Build a CDN factory function.
|
|
203
|
+
*
|
|
204
|
+
* @param id - Unique identifier for the CDN
|
|
205
|
+
* @param props - CDN configuration properties
|
|
206
|
+
* @returns Factory function that creates the CDN when invoked
|
|
207
|
+
*/
|
|
208
|
+
static build(id, props) {
|
|
209
|
+
return (_app, scope) => {
|
|
210
|
+
validateCdnProps(props);
|
|
211
|
+
return new Cdn(scope, id, props);
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
exports.CdnFactory = CdnFactory;
|
|
216
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vbGliL3BhdHRlcm5zL2F3cy9jZG4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBT0EsaURBTWlDO0FBQ2pDLHVDQUFzQztBQUN0Qyx1Q0FBb0M7QUFvRXBDOztHQUVHO0FBQ0gsU0FBUyxnQkFBZ0IsQ0FBQyxLQUFnQjtJQUN4QyxzQ0FBc0M7SUFDdEMsSUFBSSxLQUFLLENBQUMsV0FBVyxJQUFJLEtBQUssQ0FBQyxXQUFXLElBQUksS0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDM0UsT0FBTyxDQUFDLElBQUksQ0FDVixxRUFBcUU7WUFDbkUsbURBQW1ELENBQ3RELENBQUM7SUFDSixDQUFDO0lBRUQsNENBQTRDO0lBQzVDLElBQUksS0FBSyxDQUFDLFdBQVcsSUFBSSxLQUFLLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDNUUsT0FBTyxDQUFDLElBQUksQ0FDViwwRUFBMEU7WUFDeEUsOERBQThELENBQ2pFLENBQUM7SUFDSixDQUFDO0lBRUQsc0JBQXNCO0lBQ3RCLElBQUksS0FBSyxDQUFDLFVBQVUsS0FBSyxLQUFLLEVBQUUsQ0FBQztRQUMvQixNQUFNLFFBQVEsR0FBRyxLQUFvQixDQUFDO1FBQ3RDLElBQUksUUFBUSxDQUFDLFlBQVksWUFBWSxpQkFBTyxFQUFFLENBQUM7WUFDN0MsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLFlBQVksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNuRCxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ1IsTUFBTSxJQUFJLEtBQUssQ0FDYixrREFBa0Q7b0JBQ2hELDZEQUE2RCxDQUNoRSxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsd0JBQXdCO0lBQ3hCLElBQUksS0FBSyxDQUFD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SUFBSSxFQUFFLEtBQUs7d0JBQ1gsWUFBWTtxQkFDYixDQUFDO2dCQUNKLENBQUM7WUFDSCxDQUFDO1lBRUQsSUFBSSxXQUFXLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQzdCLE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDOUMsSUFBSSxXQUFXLEVBQUUsQ0FBQztvQkFDaEIsd0NBQXdDO29CQUN4QyxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztvQkFDakMsT0FBTzt3QkFDTCxJQUFJLEVBQUUsTUFBTTt3QkFDWixVQUFVLEVBQUUsR0FBRyxDQUFDLFFBQVE7cUJBQ3pCLENBQUM7Z0JBQ0osQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxJQUFJLEtBQUssQ0FDYiw4Q0FBOEMsT0FBTyxRQUFRLElBQUk7WUFDL0QseURBQXlELENBQzVELENBQUM7SUFDSixDQUFDO0NBQ0Y7QUE5SEQsa0JBOEhDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQ0c7QUFDSCxNQUFhLFVBQVU7SUFDckI7Ozs7OztPQU1HO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFVLEVBQUUsS0FBZ0I7UUFDdkMsT0FBTyxDQUFDLElBQVMsRUFBRSxLQUFnQixFQUFPLEVBQUU7WUFDMUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDeEIsT0FBTyxJQUFJLEdBQUcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ25DLENBQUMsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQWRELGdDQWNDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IHR5cGUgSUJ1Y2tldCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczNcIjtcbmltcG9ydCB7IHR5cGUgSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lbGFzdGljbG9hZGJhbGFuY2luZ3YyXCI7XG5pbXBvcnQgeyB0eXBlIElDZXJ0aWZpY2F0ZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2VydGlmaWNhdGVtYW5hZ2VyXCI7XG5pbXBvcnQgeyB0eXBlIElDYWNoZVBvbGljeSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWRmcm9udFwiO1xuXG5pbXBvcnQgdHlwZSBBcHAgZnJvbSBcIi4uLy4uL2FwcFwiO1xuaW1wb3J0IHtcbiAgQ2xvdWRGcm9udERpc3RyaWJ1dGlvbixcbiAgdHlwZSBDbG91ZEZyb250RGlzdHJpYnV0aW9uUHJvcHMsXG4gIHR5cGUgQ2RuT3JpZ2luQ29uZmlnLFxuICB0eXBlIENkbkJlaGF2aW91cixcbiAgdHlwZSBDYWNoZVBvbGljeVByZXNldFxufSBmcm9tIFwiLi4vLi4vcmVzb3VyY2VzL2F3cy9jZG5cIjtcbmltcG9ydCB7IFMzU3RvcmFnZSB9IGZyb20gXCIuL3N0b3JhZ2VcIjtcbmltcG9ydCB7IENvbXB1dGUgfSBmcm9tIFwiLi9jb21wdXRlXCI7XG5cbi8qKlxuICogUzMgb3JpZ2luIENETiBwcm9wcyAtIHVzZSB3aXRoIFMzIGJ1Y2tldFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFMzQ2RuUHJvcHMge1xuICBvcmlnaW5UeXBlOiBcInMzXCI7XG4gIGJ1Y2tldDogSUJ1Y2tldCB8IFMzU3RvcmFnZTtcbiAgb3JpZ2luUGF0aD86IHN0cmluZztcbiAgY2FjaGVQb2xpY3k/OiBDYWNoZVBvbGljeVByZXNldCB8IElDYWNoZVBvbGljeTtcbiAgYmVoYXZpb3Vycz86IENkbkJlaGF2aW91cltdO1xuICBkb21haW5OYW1lcz86IHN0cmluZ1tdO1xuICBjZXJ0aWZpY2F0ZT86IElDZXJ0aWZpY2F0ZTtcbiAgY29tbWVudD86IHN0cmluZztcbiAgZW5hYmxlTG9nZ2luZz86IGJvb2xlYW47XG4gIGxvZ0J1Y2tldD86IElCdWNrZXQ7XG59XG5cbi8qKlxuICogQUxCIG9yaWdpbiBDRE4gcHJvcHMgLSB1c2Ugd2l0aCBBcHBsaWNhdGlvbiBMb2FkIEJhbGFuY2VyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWxiQ2RuUHJvcHMge1xuICBvcmlnaW5UeXBlOiBcImFsYlwiO1xuICBsb2FkQmFsYW5jZXI6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciB8IENvbXB1dGU7XG4gIHByb3RvY29sUG9saWN5PzogXCJIVFRQX09OTFlcIiB8IFwiSFRUUFNfT05MWVwiIHwgXCJNQVRDSF9WSUVXRVJcIjtcbiAgY2FjaGVQb2xpY3k/OiBDYWNoZVBvbGljeVByZXNldCB8IElDYWNoZVBvbGljeTtcbiAgYmVoYXZpb3Vycz86IENkbkJlaGF2aW91cltdO1xuICBkb21haW5OYW1lcz86IHN0cmluZ1tdO1xuICBjZXJ0aWZpY2F0ZT86IElDZXJ0aWZpY2F0ZTtcbiAgY29tbWVudD86IHN0cmluZztcbiAgZW5hYmxlTG9nZ2luZz86IGJvb2xlYW47XG4gIGxvZ0J1Y2tldD86IElCdWNrZXQ7XG59XG5cbi8qKlxuICogSFRUUCBvcmlnaW4gQ0ROIHByb3BzIC0gdXNlIHdpdGggY3VzdG9tIEhUVFAgZW5kcG9pbnRcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBIdHRwQ2RuUHJvcHMge1xuICBvcmlnaW5UeXBlOiBcImh0dHBcIjtcbiAgZG9tYWluTmFtZTogc3RyaW5nO1xuICBvcmlnaW5QYXRoPzogc3RyaW5nO1xuICBwcm90b2NvbFBvbGljeT86IFwiSFRUUF9PTkxZXCIgfCBcIkhUVFBTX09OTFlcIiB8IFwiTUFUQ0hfVklFV0VSXCI7XG4gIGNhY2hlUG9saWN5PzogQ2FjaGVQb2xpY3lQcmVzZXQgfCBJQ2FjaGVQb2xpY3k7XG4gIGJlaGF2aW91cnM/OiBDZG5CZWhhdmlvdXJbXTtcbiAgZG9tYWluTmFtZXM/OiBzdHJpbmdbXTtcbiAgY2VydGlmaWNhdGU/OiBJQ2VydGlmaWNhdGU7XG4gIGNvbW1lbnQ/OiBzdHJpbmc7XG4gIGVuYWJsZUxvZ2dpbmc/OiBib29sZWFuO1xuICBsb2dCdWNrZXQ/OiBJQnVja2V0O1xufVxuXG4vKipcbiAqIFNtYXJ0IG9yaWdpbiBDRE4gcHJvcHMgLSBhdXRvLWRldGVjdCBvcmlnaW4gdHlwZSBmcm9tIEZqYWxsIHJlc291cmNlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU21hcnRDZG5Qcm9wcyB7XG4gIG9yaWdpblR5cGU6IFwiYXV0b1wiO1xuICBvcmlnaW46IFMzU3RvcmFnZSB8IENvbXB1dGUgfCBzdHJpbmc7XG4gIGNhY2hlUG9saWN5PzogQ2FjaGVQb2xpY3lQcmVzZXQgfCBJQ2FjaGVQb2xpY3k7XG4gIGJlaGF2aW91cnM/OiBDZG5CZWhhdmlvdXJbXTtcbiAgZG9tYWluTmFtZXM/OiBzdHJpbmdbXTtcbiAgY2VydGlmaWNhdGU/OiBJQ2VydGlmaWNhdGU7XG4gIGNvbW1lbnQ/OiBzdHJpbmc7XG4gIGVuYWJsZUxvZ2dpbmc/OiBib29sZWFuO1xuICBsb2dCdWNrZXQ/OiBJQnVja2V0O1xufVxuXG5leHBvcnQgdHlwZSBJQ2RuUHJvcHMgPSBTM0NkblByb3BzIHwgQWxiQ2RuUHJvcHMgfCBIdHRwQ2RuUHJvcHMgfCBTbWFydENkblByb3BzO1xuXG4vKipcbiAqIFZhbGlkYXRlcyBDRE4gcHJvcHMgYW5kIGxvZ3Mgd2FybmluZ3MgZm9yIG1pc2NvbmZpZ3VyZWQgb3B0aW9ucy5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVDZG5Qcm9wcyhwcm9wczogSUNkblByb3BzKTogdm9pZCB7XG4gIC8vIFZhbGlkYXRlIGNlcnRpZmljYXRlIHJlZ2lvbiB3YXJuaW5nXG4gIGlmIChwcm9wcy5jZXJ0aWZpY2F0ZSAmJiBwcm9wcy5kb21haW5OYW1lcyAmJiBwcm9wcy5kb21haW5OYW1lcy5sZW5ndGggPiAwKSB7XG4gICAgY29uc29sZS5pbmZvKFxuICAgICAgXCJbRmphbGxdIE5vdGU6IENsb3VkRnJvbnQgY2VydGlmaWNhdGVzIG11c3QgYmUgaW4gdXMtZWFzdC0xIHJlZ2lvbi4gXCIgK1xuICAgICAgICBcIkVuc3VyZSB5b3VyIGNlcnRpZmljYXRlIHdhcyBjcmVhdGVkIGluIHVzLWVhc3QtMS5cIlxuICAgICk7XG4gIH1cblxuICAvLyBWYWxpZGF0ZSBkb21haW4gbmFtZXMgcmVxdWlyZSBjZXJ0aWZpY2F0ZVxuICBpZiAocHJvcHMuZG9tYWluTmFtZXMgJiYgcHJvcHMuZG9tYWluTmFtZXMubGVuZ3RoID4gMCAmJiAhcHJvcHMuY2VydGlmaWNhdGUpIHtcbiAgICBjb25zb2xlLndhcm4oXG4gICAgICBcIltGamFsbF0gV2FybmluZzogJ2RvbWFpbk5hbWVzJyBwcm92aWRlZCBidXQgbm8gJ2NlcnRpZmljYXRlJyBzcGVjaWZpZWQuIFwiICtcbiAgICAgICAgXCJDdXN0b20gZG9tYWluIG5hbWVzIHJlcXVpcmUgYW4gQUNNIGNlcnRpZmljYXRlIGluIHVzLWVhc3QtMS5cIlxuICAgICk7XG4gIH1cblxuICAvLyBWYWxpZGF0ZSBBTEIgb3JpZ2luXG4gIGlmIChwcm9wcy5vcmlnaW5UeXBlID09PSBcImFsYlwiKSB7XG4gICAgY29uc3QgYWxiUHJvcHMgPSBwcm9wcyBhcyBBbGJDZG5Qcm9wcztcbiAgICBpZiAoYWxiUHJvcHMubG9hZEJhbGFuY2VyIGluc3RhbmNlb2YgQ29tcHV0ZSkge1xuICAgICAgY29uc3QgbGIgPSBhbGJQcm9wcy5sb2FkQmFsYW5jZXIuZ2V0TG9hZEJhbGFuY2VyKCk7XG4gICAgICBpZiAoIWxiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBcIkNvbXB1dGUgcmVzb3VyY2UgZG9lcyBub3QgaGF2ZSBhIGxvYWQgYmFsYW5jZXIuIFwiICtcbiAgICAgICAgICAgIFwiRW5zdXJlIEVDUyBjb21wdXRlIGhhcyBsb2FkQmFsYW5jZXIgZW5hYmxlZCBmb3IgQ0ROIG9yaWdpbi5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFZhbGlkYXRlIHNtYXJ0IG9yaWdpblxuICBpZiAocHJvcHMub3JpZ2luVHlwZSA9PT0gXCJhdXRvXCIpIHtcbiAgICBjb25zdCBzbWFydFByb3BzID0gcHJvcHMgYXMgU21hcnRDZG5Qcm9wcztcbiAgICBpZiAoc21hcnRQcm9wcy5vcmlnaW4gaW5zdGFuY2VvZiBDb21wdXRlKSB7XG4gICAgICBjb25zdCBjb21wdXRlVHlwZSA9IHNtYXJ0UHJvcHMub3JpZ2luLmdldENvbXB1dGVUeXBlKCk7XG4gICAgICBpZiAoY29tcHV0ZVR5cGUgPT09IFwiZWMyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIFwiRUMyIGNvbXB1dGUgdHlwZSBpcyBub3Qgc3VwcG9ydGVkIGZvciBDRE4gb3JpZ2luLiBcIiArXG4gICAgICAgICAgICBcIlVzZSBFQ1Mgd2l0aCBsb2FkIGJhbGFuY2VyIG9yIExhbWJkYSB3aXRoIGZ1bmN0aW9uIFVSTC5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKGNvbXB1dGVUeXBlID09PSBcImVjc1wiICYmICFzbWFydFByb3BzLm9yaWdpbi5nZXRMb2FkQmFsYW5jZXIoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgXCJFQ1MgY29tcHV0ZSBtdXN0IGhhdmUgYSBsb2FkIGJhbGFuY2VyIGZvciBDRE4gb3JpZ2luLiBcIiArXG4gICAgICAgICAgICBcIkVuYWJsZSBsb2FkQmFsYW5jZXIgaW4geW91ciBFQ1MgY29tcHV0ZSBjb25maWd1cmF0aW9uLlwiXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoY29tcHV0ZVR5cGUgPT09IFwibGFtYmRhXCIgJiYgIXNtYXJ0UHJvcHMub3JpZ2luLmdldEZ1bmN0aW9uVXJsKCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIFwiTGFtYmRhIGNvbXB1dGUgbXVzdCBoYXZlIGEgZnVuY3Rpb24gVVJMIGZvciBDRE4gb3JpZ2luLiBcIiArXG4gICAgICAgICAgICBcIkVuYWJsZSBmdW5jdGlvblVybCBpbiB5b3VyIExhbWJkYSBjb21wdXRlIGNvbmZpZ3VyYXRpb24uXCJcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDRE4gd3JhcHBlciBjbGFzcyB0aGF0IGV4dGVuZHMgQ2xvdWRGcm9udERpc3RyaWJ1dGlvbiB3aXRoIEZqYWxsIHBhdHRlcm5zLlxuICovXG5leHBvcnQgY2xhc3MgQ2RuIGV4dGVuZHMgQ2xvdWRGcm9udERpc3RyaWJ1dGlvbiB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBJQ2RuUHJvcHMpIHtcbiAgICBjb25zdCByZXNvbHZlZFByb3BzID0gQ2RuLnJlc29sdmVQcm9wcyhwcm9wcyk7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCByZXNvbHZlZFByb3BzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIElDZG5Qcm9wcyB0byBDbG91ZEZyb250RGlzdHJpYnV0aW9uUHJvcHMuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyByZXNvbHZlUHJvcHMocHJvcHM6IElDZG5Qcm9wcyk6IENsb3VkRnJvbnREaXN0cmlidXRpb25Qcm9wcyB7XG4gICAgY29uc3QgZGVmYXVsdE9yaWdpbiA9IENkbi5yZXNvbHZlRGVmYXVsdE9yaWdpbihwcm9wcyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGVmYXVsdE9yaWdpbixcbiAgICAgIGRlZmF1bHRDYWNoZVBvbGljeTogcHJvcHMuY2FjaGVQb2xpY3ksXG4gICAgICBiZWhhdmlvdXJzOiBwcm9wcy5iZWhhdmlvdXJzLFxuICAgICAgZG9tYWluTmFtZXM6IHByb3BzLmRvbWFpbk5hbWVzLFxuICAgICAgY2VydGlmaWNhdGU6IHByb3BzLmNlcnRpZmljYXRlLFxuICAgICAgY29tbWVudDogcHJvcHMuY29tbWVudCxcbiAgICAgIGVuYWJsZUxvZ2dpbmc6IHByb3BzLmVuYWJsZUxvZ2dpbmcsXG4gICAgICBsb2dCdWNrZXQ6IHByb3BzLmxvZ0J1Y2tldFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSB0aGUgZGVmYXVsdCBvcmlnaW4gZnJvbSBJQ2RuUHJvcHMuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyByZXNvbHZlRGVmYXVsdE9yaWdpbihwcm9wczogSUNkblByb3BzKTogQ2RuT3JpZ2luQ29uZmlnIHtcbiAgICBzd2l0Y2ggKHByb3BzLm9yaWdpblR5cGUpIHtcbiAgICAgIGNhc2UgXCJzM1wiOiB7XG4gICAgICAgIGNvbnN0IHMzUHJvcHMgPSBwcm9wcyBhcyBTM0NkblByb3BzO1xuICAgICAgICBjb25zdCBidWNrZXQgPVxuICAgICAgICAgIHMzUHJvcHMuYnVja2V0IGluc3RhbmNlb2YgUzNTdG9yYWdlXG4gICAgICAgICAgICA/IHMzUHJvcHMuYnVja2V0LmdldEJ1Y2tldCgpXG4gICAgICAgICAgICA6IHMzUHJvcHMuYnVja2V0O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHR5cGU6IFwiczNcIixcbiAgICAgICAgICBidWNrZXQsXG4gICAgICAgICAgb3JpZ2luUGF0aDogczNQcm9wcy5vcmlnaW5QYXRoXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNhc2UgXCJhbGJcIjoge1xuICAgICAgICBjb25zdCBhbGJQcm9wcyA9IHByb3BzIGFzIEFsYkNkblByb3BzO1xuICAgICAgICBjb25zdCBsb2FkQmFsYW5jZXIgPVxuICAgICAgICAgIGFsYlByb3BzLmxvYWRCYWxhbmNlciBpbnN0YW5jZW9mIENvbXB1dGVcbiAgICAgICAgICAgID8gYWxiUHJvcHMubG9hZEJhbGFuY2VyLmdldExvYWRCYWxhbmNlcigpIVxuICAgICAgICAgICAgOiBhbGJQcm9wcy5sb2FkQmFsYW5jZXI7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdHlwZTogXCJhbGJcIixcbiAgICAgICAgICBsb2FkQmFsYW5jZXIsXG4gICAgICAgICAgcHJvdG9jb2xQb2xpY3k6IGFsYlByb3BzLnByb3RvY29sUG9saWN5XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNhc2UgXCJodHRwXCI6IHtcbiAgICAgICAgY29uc3QgaHR0cFByb3BzID0gcHJvcHMgYXMgSHR0cENkblByb3BzO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHR5cGU6IFwiaHR0cFwiLFxuICAgICAgICAgIGRvbWFpbk5hbWU6IGh0dHBQcm9wcy5kb21haW5OYW1lLFxuICAgICAgICAgIG9yaWdpblBhdGg6IGh0dHBQcm9wcy5vcmlnaW5QYXRoLFxuICAgICAgICAgIHByb3RvY29sUG9saWN5OiBodHRwUHJvcHMucHJvdG9jb2xQb2xpY3lcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY2FzZSBcImF1dG9cIjoge1xuICAgICAgICBjb25zdCBzbWFydFByb3BzID0gcHJvcHMgYXMgU21hcnRDZG5Qcm9wcztcbiAgICAgICAgcmV0dXJuIENkbi5kZXRlY3RPcmlnaW5Gcm9tUmVzb3VyY2Uoc21hcnRQcm9wcy5vcmlnaW4pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBdXRvLWRldGVjdCBvcmlnaW4gY29uZmlndXJhdGlvbiBmcm9tIGEgRmphbGwgcmVzb3VyY2UuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBkZXRlY3RPcmlnaW5Gcm9tUmVzb3VyY2UoXG4gICAgcmVzb3VyY2U6IFMzU3RvcmFnZSB8IENvbXB1dGUgfCBzdHJpbmdcbiAgKTogQ2RuT3JpZ2luQ29uZmlnIHtcbiAgICAvLyBTdHJpbmcg4oaSIEhUVFAgb3JpZ2luXG4gICAgaWYgKHR5cGVvZiByZXNvdXJjZSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogXCJodHRwXCIsXG4gICAgICAgIGRvbWFpbk5hbWU6IHJlc291cmNlXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIFMzU3RvcmFnZSDihpIgUzMgb3JpZ2luXG4gICAgaWYgKHJlc291cmNlIGluc3RhbmNlb2YgUzNTdG9yYWdlKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBcInMzXCIsXG4gICAgICAgIGJ1Y2tldDogcmVzb3VyY2UuZ2V0QnVja2V0KClcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gQ29tcHV0ZSDihpIgQUxCIG9yIExhbWJkYSBvcmlnaW5cbiAgICBpZiAocmVzb3VyY2UgaW5zdGFuY2VvZiBDb21wdXRlKSB7XG4gICAgICBjb25zdCBjb21wdXRlVHlwZSA9IHJlc291cmNlLmdldENvbXB1dGVUeXBlKCk7XG5cbiAgICAgIGlmIChjb21wdXRlVHlwZSA9PT0gXCJlY3NcIikge1xuICAgICAgICBjb25zdCBsb2FkQmFsYW5jZXIgPSByZXNvdXJjZS5nZXRMb2FkQmFsYW5jZXIoKTtcbiAgICAgICAgaWYgKGxvYWRCYWxhbmNlcikge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiBcImFsYlwiLFxuICAgICAgICAgICAgbG9hZEJhbGFuY2VyXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoY29tcHV0ZVR5cGUgPT09IFwibGFtYmRhXCIpIHtcbiAgICAgICAgY29uc3QgZnVuY3Rpb25VcmwgPSByZXNvdXJjZS5nZXRGdW5jdGlvblVybCgpO1xuICAgICAgICBpZiAoZnVuY3Rpb25VcmwpIHtcbiAgICAgICAgICAvLyBMYW1iZGEgZnVuY3Rpb24gVVJMIGlzIGFuIEhUVFAgb3JpZ2luXG4gICAgICAgICAgY29uc3QgdXJsID0gbmV3IFVSTChmdW5jdGlvblVybCk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6IFwiaHR0cFwiLFxuICAgICAgICAgICAgZG9tYWluTmFtZTogdXJsLmhvc3RuYW1lXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBVbmFibGUgdG8gZGV0ZWN0IENETiBvcmlnaW4gZnJvbSByZXNvdXJjZTogJHt0eXBlb2YgcmVzb3VyY2V9LiBgICtcbiAgICAgICAgXCJQcm92aWRlIGV4cGxpY2l0IG9yaWdpbiBjb25maWd1cmF0aW9uIHVzaW5nIG9yaWdpblR5cGUuXCJcbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogRmFjdG9yeSBmb3IgY3JlYXRpbmcgQ0ROIChDbG91ZEZyb250KSBkaXN0cmlidXRpb25zLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTMyBvcmlnaW5cbiAqIGNvbnN0IGFzc2V0cyA9IGFwcC5hZGRTdG9yYWdlKFN0b3JhZ2VGYWN0b3J5LmJ1aWxkKFwiQXNzZXRzXCIsIHsgYnVja2V0VHlwZTogXCJwcml2YXRlXCIgfSkpO1xuICogYXBwLmFkZENkbihDZG5GYWN0b3J5LmJ1aWxkKFwiQXNzZXRzQ2RuXCIsIHtcbiAqICAgb3JpZ2luVHlwZTogXCJzM1wiLFxuICogICBidWNrZXQ6IGFzc2V0c1xuICogfSkpO1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBBTEIgb3JpZ2luIChFQ1MpXG4gKiBjb25zdCBhcGkgPSBhcHAuYWRkQ29tcHV0ZShDb21wdXRlRmFjdG9yeS5idWlsZChcIkFwaVwiLCB7IHR5cGU6IFwiZWNzXCIsIC4uLiB9KSk7XG4gKiBhcHAuYWRkQ2RuKENkbkZhY3RvcnkuYnVpbGQoXCJBcGlDZG5cIiwge1xuICogICBvcmlnaW5UeXBlOiBcImFsYlwiLFxuICogICBsb2FkQmFsYW5jZXI6IGFwaVxuICogfSkpO1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTbWFydCBkZXRlY3Rpb25cbiAqIGFwcC5hZGRDZG4oQ2RuRmFjdG9yeS5idWlsZChcIkFwcENkblwiLCB7XG4gKiAgIG9yaWdpblR5cGU6IFwiYXV0b1wiLFxuICogICBvcmlnaW46IGFzc2V0c1xuICogfSkpO1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBDdXN0b20gZG9tYWluXG4gKiBhcHAuYWRkQ2RuKENkbkZhY3RvcnkuYnVpbGQoXCJBcHBDZG5cIiwge1xuICogICBvcmlnaW5UeXBlOiBcInMzXCIsXG4gKiAgIGJ1Y2tldDogYXNzZXRzLFxuICogICBkb21haW5OYW1lczogW1wiYXBwLmV4YW1wbGUuY29tXCJdLFxuICogICBjZXJ0aWZpY2F0ZTogbXlDZXJ0XG4gKiB9KSk7XG4gKi9cbmV4cG9ydCBjbGFzcyBDZG5GYWN0b3J5IHtcbiAgLyoqXG4gICAqIEJ1aWxkIGEgQ0ROIGZhY3RvcnkgZnVuY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSBpZCAtIFVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgQ0ROXG4gICAqIEBwYXJhbSBwcm9wcyAtIENETiBjb25maWd1cmF0aW9uIHByb3BlcnRpZXNcbiAgICogQHJldHVybnMgRmFjdG9yeSBmdW5jdGlvbiB0aGF0IGNyZWF0ZXMgdGhlIENETiB3aGVuIGludm9rZWRcbiAgICovXG4gIHN0YXRpYyBidWlsZChpZDogc3RyaW5nLCBwcm9wczogSUNkblByb3BzKSB7XG4gICAgcmV0dXJuIChfYXBwOiBBcHAsIHNjb3BlOiBDb25zdHJ1Y3QpOiBDZG4gPT4ge1xuICAgICAgdmFsaWRhdGVDZG5Qcm9wcyhwcm9wcyk7XG4gICAgICByZXR1cm4gbmV3IENkbihzY29wZSwgaWQsIHByb3BzKTtcbiAgICB9O1xuICB9XG59XG4iXX0=
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type RepositoryImage } from "aws-cdk-lib/aws-ecs";
|
|
2
2
|
import { Repository } from "aws-cdk-lib/aws-ecr";
|
|
3
|
-
import { Connections, type IConnectable, type IVpc, type UserData, type IMachineImage } from "aws-cdk-lib/aws-ec2";
|
|
3
|
+
import { type Connections, type IConnectable, type IVpc, type UserData, type IMachineImage } from "aws-cdk-lib/aws-ec2";
|
|
4
4
|
import { Code, Runtime, type FunctionUrlAuthType, type FunctionUrlCorsOptions } from "aws-cdk-lib/aws-lambda";
|
|
5
5
|
import { type PolicyStatement, type PolicyDocument, type IManagedPolicy } from "aws-cdk-lib/aws-iam";
|
|
6
6
|
import { Construct } from "constructs";
|
|
@@ -273,6 +273,26 @@ export interface EcsServiceConfig {
|
|
|
273
273
|
* ]
|
|
274
274
|
*/
|
|
275
275
|
connections?: IConnectable[];
|
|
276
|
+
/**
|
|
277
|
+
* Capacity provider for this service. REQUIRED.
|
|
278
|
+
* Each service specifies its own capacity provider.
|
|
279
|
+
*
|
|
280
|
+
* @example
|
|
281
|
+
* // Mixed FARGATE and EC2 services in same cluster
|
|
282
|
+
* {
|
|
283
|
+
* services: [
|
|
284
|
+
* { name: "api", capacityProvider: "FARGATE" },
|
|
285
|
+
* { name: "worker", capacityProvider: "EC2", ec2Config: { instanceType: "t3.micro" } }
|
|
286
|
+
* ]
|
|
287
|
+
* }
|
|
288
|
+
*/
|
|
289
|
+
capacityProvider: EcsCapacityProvider;
|
|
290
|
+
/**
|
|
291
|
+
* EC2 capacity configuration for this service.
|
|
292
|
+
* Only used when service capacityProvider is "EC2".
|
|
293
|
+
* Services with matching ec2Config share an ASG for efficiency.
|
|
294
|
+
*/
|
|
295
|
+
ec2Config?: Ec2CapacityConfig;
|
|
276
296
|
}
|
|
277
297
|
/**
|
|
278
298
|
* SSH access configuration for EC2 instances.
|
|
@@ -347,21 +367,10 @@ export interface EcsComputeProps extends BaseComputeProps {
|
|
|
347
367
|
/**
|
|
348
368
|
* Services in this cluster.
|
|
349
369
|
* Each service gets its own task definition, scaling, and target group.
|
|
370
|
+
* Each service MUST specify its own capacityProvider.
|
|
350
371
|
* All services share the cluster's ALB (unless disabled).
|
|
351
372
|
*/
|
|
352
373
|
services: EcsServiceConfig[];
|
|
353
|
-
/**
|
|
354
|
-
* Capacity provider determines infrastructure type.
|
|
355
|
-
* - "FARGATE": Serverless containers (default)
|
|
356
|
-
* - "FARGATE_SPOT": Serverless with Spot pricing
|
|
357
|
-
* - "EC2": EC2-backed containers
|
|
358
|
-
*/
|
|
359
|
-
capacityProvider?: EcsCapacityProvider;
|
|
360
|
-
/**
|
|
361
|
-
* EC2 capacity configuration.
|
|
362
|
-
* Only used when capacityProvider is "EC2".
|
|
363
|
-
*/
|
|
364
|
-
ec2Config?: Ec2CapacityConfig;
|
|
365
374
|
/**
|
|
366
375
|
* ECR repository for all services (default image).
|
|
367
376
|
* Individual services can override with their own `image` property.
|
|
@@ -403,6 +412,7 @@ interface BaseLambdaProps extends BaseComputeProps {
|
|
|
403
412
|
timeout?: number;
|
|
404
413
|
/** Memory size in MB. Default: 128 */
|
|
405
414
|
memorySize?: number;
|
|
415
|
+
ephemeralStorageSize?: number;
|
|
406
416
|
/** Lambda function description */
|
|
407
417
|
description?: string;
|
|
408
418
|
/** IAM role description */
|
|
@@ -419,6 +429,15 @@ interface BaseLambdaProps extends BaseComputeProps {
|
|
|
419
429
|
functionUrl?: FunctionUrlConfig | false;
|
|
420
430
|
/** Environment variables */
|
|
421
431
|
environment?: Record<string, string>;
|
|
432
|
+
/** Container secrets import (key: env var, value: SecretImport) */
|
|
433
|
+
containerSecretsImport?: {
|
|
434
|
+
[key: string]: SecretImport;
|
|
435
|
+
};
|
|
436
|
+
/**
|
|
437
|
+
* Resources this Lambda needs to connect to (e.g., databases).
|
|
438
|
+
* Creates security group rules to allow traffic from this Lambda.
|
|
439
|
+
*/
|
|
440
|
+
connections?: IConnectable[];
|
|
422
441
|
}
|
|
423
442
|
/**
|
|
424
443
|
* Container-based Lambda using ECR image.
|