@rio-cloud/cdk-v2-constructs 1.0.1-alpha.0
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/.gitattributes +15 -0
- package/.jsii +7832 -0
- package/.versionrc.json +14 -0
- package/API.md +8136 -0
- package/CHANGELOG.md +5 -0
- package/LICENSE +202 -0
- package/README.md +56 -0
- package/lib/datadog/datadogLogIndexMonitoring.d.ts +49 -0
- package/lib/datadog/datadogLogIndexMonitoring.js +116 -0
- package/lib/datadog/datadogMonitor.d.ts +13 -0
- package/lib/datadog/datadogMonitor.js +19 -0
- package/lib/datadog/index.d.ts +1 -0
- package/lib/datadog/index.js +19 -0
- package/lib/fargate/datadog.d.ts +18 -0
- package/lib/fargate/datadog.js +225 -0
- package/lib/fargate/rio-fargate-service.d.ts +276 -0
- package/lib/fargate/rio-fargate-service.js +147 -0
- package/lib/fargate/spring.d.ts +6 -0
- package/lib/fargate/spring.js +39 -0
- package/lib/index.d.ts +21 -0
- package/lib/index.js +34 -0
- package/lib/kafka/index.d.ts +2 -0
- package/lib/kafka/index.js +15 -0
- package/lib/kafka/kafka-event-spec.d.ts +43 -0
- package/lib/kafka/kafka-event-spec.js +106 -0
- package/lib/kafka/kafka-topic.d.ts +102 -0
- package/lib/kafka/kafka-topic.js +70 -0
- package/lib/pipeline/rio-backup-secrets-restore-stage.d.ts +40 -0
- package/lib/pipeline/rio-backup-secrets-restore-stage.js +104 -0
- package/lib/pipeline/rio-bitbucket-source-action.d.ts +25 -0
- package/lib/pipeline/rio-bitbucket-source-action.js +36 -0
- package/lib/rio-claidometer.d.ts +21 -0
- package/lib/rio-claidometer.js +39 -0
- package/lib/rio-landing-zone.d.ts +16 -0
- package/lib/rio-landing-zone.js +57 -0
- package/lib/rio-load-balancer.d.ts +26 -0
- package/lib/rio-load-balancer.js +42 -0
- package/lib/toggle.d.ts +21 -0
- package/lib/toggle.js +44 -0
- package/lib/watchful/alb.d.ts +47 -0
- package/lib/watchful/alb.js +52 -0
- package/lib/watchful/aspect.d.ts +16 -0
- package/lib/watchful/aspect.js +55 -0
- package/lib/watchful/cloudfront.d.ts +50 -0
- package/lib/watchful/cloudfront.js +65 -0
- package/lib/watchful/datadog-log-alarm.d.ts +37 -0
- package/lib/watchful/datadog-log-alarm.js +88 -0
- package/lib/watchful/datadog-metric-alarm.d.ts +32 -0
- package/lib/watchful/datadog-metric-alarm.js +158 -0
- package/lib/watchful/docdb.d.ts +62 -0
- package/lib/watchful/docdb.js +102 -0
- package/lib/watchful/dynamodb.d.ts +69 -0
- package/lib/watchful/dynamodb.js +87 -0
- package/lib/watchful/ecs.d.ts +50 -0
- package/lib/watchful/ecs.js +69 -0
- package/lib/watchful/lambda.d.ts +59 -0
- package/lib/watchful/lambda.js +65 -0
- package/lib/watchful/metric-alarm.d.ts +34 -0
- package/lib/watchful/metric-alarm.js +3 -0
- package/lib/watchful/rds.d.ts +47 -0
- package/lib/watchful/rds.js +47 -0
- package/lib/watchful/targetgroup.d.ts +47 -0
- package/lib/watchful/targetgroup.js +54 -0
- package/lib/watchful/upperToLower.d.ts +7 -0
- package/lib/watchful/upperToLower.js +35 -0
- package/lib/watchful/watchful.d.ts +119 -0
- package/lib/watchful/watchful.js +182 -0
- package/node_modules/argparse/CHANGELOG.md +216 -0
- package/node_modules/argparse/LICENSE +254 -0
- package/node_modules/argparse/README.md +84 -0
- package/node_modules/argparse/argparse.js +3707 -0
- package/node_modules/argparse/lib/sub.js +67 -0
- package/node_modules/argparse/lib/textwrap.js +440 -0
- package/node_modules/argparse/package.json +31 -0
- package/node_modules/js-yaml/CHANGELOG.md +616 -0
- package/node_modules/js-yaml/LICENSE +21 -0
- package/node_modules/js-yaml/README.md +246 -0
- package/node_modules/js-yaml/bin/js-yaml.js +126 -0
- package/node_modules/js-yaml/dist/js-yaml.js +3874 -0
- package/node_modules/js-yaml/dist/js-yaml.min.js +2 -0
- package/node_modules/js-yaml/dist/js-yaml.mjs +3851 -0
- package/node_modules/js-yaml/index.js +47 -0
- package/node_modules/js-yaml/lib/common.js +59 -0
- package/node_modules/js-yaml/lib/dumper.js +965 -0
- package/node_modules/js-yaml/lib/exception.js +55 -0
- package/node_modules/js-yaml/lib/loader.js +1727 -0
- package/node_modules/js-yaml/lib/schema/core.js +11 -0
- package/node_modules/js-yaml/lib/schema/default.js +22 -0
- package/node_modules/js-yaml/lib/schema/failsafe.js +17 -0
- package/node_modules/js-yaml/lib/schema/json.js +19 -0
- package/node_modules/js-yaml/lib/schema.js +121 -0
- package/node_modules/js-yaml/lib/snippet.js +101 -0
- package/node_modules/js-yaml/lib/type/binary.js +125 -0
- package/node_modules/js-yaml/lib/type/bool.js +35 -0
- package/node_modules/js-yaml/lib/type/float.js +97 -0
- package/node_modules/js-yaml/lib/type/int.js +156 -0
- package/node_modules/js-yaml/lib/type/map.js +8 -0
- package/node_modules/js-yaml/lib/type/merge.js +12 -0
- package/node_modules/js-yaml/lib/type/null.js +35 -0
- package/node_modules/js-yaml/lib/type/omap.js +44 -0
- package/node_modules/js-yaml/lib/type/pairs.js +53 -0
- package/node_modules/js-yaml/lib/type/seq.js +8 -0
- package/node_modules/js-yaml/lib/type/set.js +29 -0
- package/node_modules/js-yaml/lib/type/str.js +8 -0
- package/node_modules/js-yaml/lib/type/timestamp.js +88 -0
- package/node_modules/js-yaml/lib/type.js +66 -0
- package/node_modules/js-yaml/package.json +66 -0
- package/package.json +126 -0
- package/release-commit-check.js +6 -0
- package/version.json +3 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DataDog = void 0;
|
|
4
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
5
|
+
const ecs = require("aws-cdk-lib/aws-ecs");
|
|
6
|
+
const lambda = require("aws-cdk-lib/aws-lambda");
|
|
7
|
+
const logs = require("aws-cdk-lib/aws-logs");
|
|
8
|
+
const rio_fargate_service_1 = require("./rio-fargate-service");
|
|
9
|
+
class DataDog {
|
|
10
|
+
static getFargateContainerEnvironmentVariables(scope, stage, serviceName, version, accountName, teamName) {
|
|
11
|
+
const { account: accountId, region } = aws_cdk_lib_1.Stack.of(scope);
|
|
12
|
+
return {
|
|
13
|
+
// unified tagging, see https://docs.datadoghq.com/getting_started/tagging/unified_service_tagging/?tab=ecs
|
|
14
|
+
DD_ENV: stage,
|
|
15
|
+
DD_SERVICE: serviceName,
|
|
16
|
+
DD_VERSION: version,
|
|
17
|
+
// APM and tracing, see https://docs.datadoghq.com/tracing/setup_overview/setup/java/?tab=containers
|
|
18
|
+
DD_LOGS_INJECTION: 'true',
|
|
19
|
+
DD_SERVICE_MAPPING: this.getApmServiceMappingEnvironmentVariableValue(serviceName),
|
|
20
|
+
DD_TAGS: this.getTagsEnvironmentVariableValue(accountId, accountName, region, teamName, stage, serviceName, version, 'service'),
|
|
21
|
+
DD_TRACE_SAMPLE_RATE: '1.0',
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
// we add all possible service mappings here even if not used in a particular service to get globally unique names
|
|
25
|
+
static getApmServiceMappingEnvironmentVariableValue(serviceName) {
|
|
26
|
+
const serviceMapping = {
|
|
27
|
+
'database': `${serviceName}-aurora`,
|
|
28
|
+
'java-aws-sdk': `${serviceName}-aws-sdk`,
|
|
29
|
+
'kafka': `${serviceName}-kafka`,
|
|
30
|
+
'mysql': `${serviceName}-aurora`,
|
|
31
|
+
'redis': `${serviceName}-redis`,
|
|
32
|
+
};
|
|
33
|
+
return Object.entries(serviceMapping)
|
|
34
|
+
.map(([key, value]) => `${key}:${value}`)
|
|
35
|
+
.join(',');
|
|
36
|
+
}
|
|
37
|
+
static getFargateDockerLabels(stage, serviceName, version) {
|
|
38
|
+
return {
|
|
39
|
+
'com.datadoghq.tags.env': stage,
|
|
40
|
+
'com.datadoghq.tags.service': serviceName,
|
|
41
|
+
'com.datadoghq.tags.version': version,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
static addDatadogSidecar(scope, taskDefinition, accountName, teamName, stage, serviceName, version, datadogApiKeyParameter, datadogSite, datadogLoggingMode, apmGetResourcesToIgnore, cpu, memoryLimitMiB, essential, containerTag) {
|
|
45
|
+
const { account: accountId, region } = aws_cdk_lib_1.Stack.of(scope);
|
|
46
|
+
const datadogSidecar = taskDefinition.addContainer('datadog-agent', {
|
|
47
|
+
image: ecs.ContainerImage.fromRegistry(`public.ecr.aws/datadog/agent:${containerTag}`),
|
|
48
|
+
logging: this.setupLogging(scope, accountName, teamName, stage, serviceName, version, datadogApiKeyParameter, datadogLoggingMode, datadogSite, 'datadog-sidecar'),
|
|
49
|
+
cpu,
|
|
50
|
+
memoryLimitMiB,
|
|
51
|
+
environment: {
|
|
52
|
+
// unified tagging, see https://docs.datadoghq.com/getting_started/tagging/unified_service_tagging/?tab=ecs
|
|
53
|
+
DD_ENV: stage,
|
|
54
|
+
DD_SERVICE: serviceName,
|
|
55
|
+
DD_VERSION: version,
|
|
56
|
+
// APM and tracing see https://docs.datadoghq.com/agent/docker/apm/?tab=linux
|
|
57
|
+
DD_APM_ENABLED: 'true',
|
|
58
|
+
DD_APM_IGNORE_RESOURCES: apmGetResourcesToIgnore
|
|
59
|
+
.map((apmGetResourceToIgnore) => `GET ${apmGetResourceToIgnore}`)
|
|
60
|
+
.join(','),
|
|
61
|
+
// general settings
|
|
62
|
+
DD_SITE: datadogSite,
|
|
63
|
+
DD_TAGS: this.getTagsEnvironmentVariableValue(accountId, accountName, region, teamName, stage, serviceName, version, 'datadog-sidecar'),
|
|
64
|
+
ECS_FARGATE: 'true',
|
|
65
|
+
DD_COLLECT_GCE_TAGS: 'false',
|
|
66
|
+
},
|
|
67
|
+
// see https://github.com/DataDog/datadog-agent/blob/master/Dockerfiles/agent/amd64/Dockerfile#L171-L172
|
|
68
|
+
healthCheck: {
|
|
69
|
+
startPeriod: aws_cdk_lib_1.Duration.minutes(2),
|
|
70
|
+
interval: aws_cdk_lib_1.Duration.seconds(30),
|
|
71
|
+
timeout: aws_cdk_lib_1.Duration.seconds(5),
|
|
72
|
+
retries: 2,
|
|
73
|
+
command: ['CMD-SHELL', '/probe.sh'],
|
|
74
|
+
},
|
|
75
|
+
secrets: {
|
|
76
|
+
DD_API_KEY: ecs.Secret.fromSsmParameter(datadogApiKeyParameter),
|
|
77
|
+
},
|
|
78
|
+
essential: essential,
|
|
79
|
+
});
|
|
80
|
+
datadogSidecar.addPortMappings({
|
|
81
|
+
containerPort: 8125,
|
|
82
|
+
protocol: ecs.Protocol.UDP,
|
|
83
|
+
});
|
|
84
|
+
datadogSidecar.addPortMappings({
|
|
85
|
+
containerPort: 8126,
|
|
86
|
+
protocol: ecs.Protocol.TCP,
|
|
87
|
+
});
|
|
88
|
+
return datadogSidecar;
|
|
89
|
+
}
|
|
90
|
+
static getTagsEnvironmentVariableValue(accountId, accountName, region, teamName, stage, serviceName, version, containerType) {
|
|
91
|
+
let separator;
|
|
92
|
+
switch (containerType) {
|
|
93
|
+
case 'service':
|
|
94
|
+
separator = ',';
|
|
95
|
+
break;
|
|
96
|
+
case 'datadog-sidecar':
|
|
97
|
+
separator = ' ';
|
|
98
|
+
break;
|
|
99
|
+
case 'fluent-bit':
|
|
100
|
+
separator = ',';
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
const tags = {
|
|
104
|
+
// unified tagging
|
|
105
|
+
// overridden by dedicated settings (environment variables/tags)
|
|
106
|
+
// duplicated here to ensure they are used (and sometimes, not all three values are supported)
|
|
107
|
+
env: stage,
|
|
108
|
+
service: serviceName,
|
|
109
|
+
version,
|
|
110
|
+
// account/team specific parts
|
|
111
|
+
account_id: accountId,
|
|
112
|
+
account_name: accountName,
|
|
113
|
+
region,
|
|
114
|
+
team: teamName,
|
|
115
|
+
};
|
|
116
|
+
return Object.entries(tags)
|
|
117
|
+
.map(([key, value]) => `${key}:${value}`)
|
|
118
|
+
.join(separator);
|
|
119
|
+
}
|
|
120
|
+
static addFireLensLogRouter(taskDefinition, cpu, memoryLimitMiB) {
|
|
121
|
+
return taskDefinition.addFirelensLogRouter('firelens-log-router', {
|
|
122
|
+
image: ecs.ContainerImage.fromRegistry('public.ecr.aws/aws-observability/aws-for-fluent-bit:latest'),
|
|
123
|
+
firelensConfig: {
|
|
124
|
+
type: ecs.FirelensLogRouterType.FLUENTBIT,
|
|
125
|
+
options: {
|
|
126
|
+
configFileType: ecs.FirelensConfigFileType.FILE,
|
|
127
|
+
configFileValue: '/fluent-bit/configs/parse-json.conf',
|
|
128
|
+
enableECSLogMetadata: true,
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
cpu,
|
|
132
|
+
memoryLimitMiB,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
static setupLogging(scope, accountName, teamName, stage, serviceName, version, datadogApiKeyParameter, datadogLoggingMode, datadogSite, containerType) {
|
|
136
|
+
let logGroupName;
|
|
137
|
+
let logGroupId;
|
|
138
|
+
let containerTypeCamelCase;
|
|
139
|
+
switch (containerType) {
|
|
140
|
+
case 'service':
|
|
141
|
+
logGroupId = 'LogGroupForService';
|
|
142
|
+
logGroupName = serviceName;
|
|
143
|
+
containerTypeCamelCase = 'Service';
|
|
144
|
+
break;
|
|
145
|
+
case 'datadog-sidecar':
|
|
146
|
+
logGroupId = 'LogGroupForDatadogSidecar';
|
|
147
|
+
logGroupName = `${serviceName}-${containerType}`;
|
|
148
|
+
containerTypeCamelCase = 'DatadogSidecar';
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
const { account: accountId, region } = aws_cdk_lib_1.Stack.of(scope);
|
|
152
|
+
switch (datadogLoggingMode) {
|
|
153
|
+
case rio_fargate_service_1.DataDogLoggingMode.AWS_FIRE_LENS:
|
|
154
|
+
// TODO can we use `secretOptions` here as well, e.g. as in https://github.com/aws-samples/amazon-ecs-firelens-examples/blob/mainline/examples/fluent-bit/datadog/task-definition.json#L33-L36
|
|
155
|
+
// Probably not, see https://github.com/aws/aws-cdk/issues/8174
|
|
156
|
+
return ecs.LogDrivers.firelens({
|
|
157
|
+
// see https://docs.datadoghq.com/integrations/fluentbit/#configuration-parameters
|
|
158
|
+
options: {
|
|
159
|
+
Name: 'datadog',
|
|
160
|
+
Match: '*',
|
|
161
|
+
Host: `http-intake.logs.${datadogSite}`,
|
|
162
|
+
TLS: 'on',
|
|
163
|
+
apikey: datadogApiKeyParameter.stringValue,
|
|
164
|
+
compress: 'gzip',
|
|
165
|
+
dd_service: logGroupName,
|
|
166
|
+
dd_source: 'rio-fargate',
|
|
167
|
+
dd_message_key: 'log',
|
|
168
|
+
dd_tags: this.getTagsEnvironmentVariableValue(accountId, accountName, region, teamName, stage, serviceName, version, 'fluent-bit'),
|
|
169
|
+
provider: 'ecs',
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
case rio_fargate_service_1.DataDogLoggingMode.FORWARDER_LAMBDA:
|
|
173
|
+
const logGroupForForwardingLambda = new logs.LogGroup(scope, logGroupId, {
|
|
174
|
+
logGroupName,
|
|
175
|
+
retention: logs.RetentionDays.ONE_WEEK,
|
|
176
|
+
});
|
|
177
|
+
const logForwarderLambdaArn = aws_cdk_lib_1.Fn.importValue('custom-resource-datadog-logforwarder-function-arn');
|
|
178
|
+
const cfnPermission = new lambda.CfnPermission(scope, `LogForwarderPermission${containerTypeCamelCase}`, {
|
|
179
|
+
action: 'lambda:InvokeFunction',
|
|
180
|
+
functionName: logForwarderLambdaArn,
|
|
181
|
+
principal: `logs.${region}.amazonaws.com`,
|
|
182
|
+
sourceArn: logGroupForForwardingLambda.logGroupArn,
|
|
183
|
+
});
|
|
184
|
+
const cfnSubscriptionFilter = new logs.CfnSubscriptionFilter(scope, `LogForwarderSubscriptionFilter${containerTypeCamelCase}`, {
|
|
185
|
+
destinationArn: logForwarderLambdaArn,
|
|
186
|
+
filterPattern: '',
|
|
187
|
+
logGroupName: logGroupForForwardingLambda.logGroupName,
|
|
188
|
+
});
|
|
189
|
+
cfnSubscriptionFilter.addDependsOn(cfnPermission);
|
|
190
|
+
return ecs.LogDrivers.awsLogs({
|
|
191
|
+
streamPrefix: containerType,
|
|
192
|
+
logGroup: logGroupForForwardingLambda,
|
|
193
|
+
});
|
|
194
|
+
case rio_fargate_service_1.DataDogLoggingMode.NONE:
|
|
195
|
+
const logGroupInCloudwatchOnly = new logs.LogGroup(scope, logGroupId, {
|
|
196
|
+
retention: logs.RetentionDays.ONE_WEEK,
|
|
197
|
+
});
|
|
198
|
+
return ecs.LogDrivers.awsLogs({
|
|
199
|
+
streamPrefix: containerType,
|
|
200
|
+
logGroup: logGroupInCloudwatchOnly,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
static ensureLoggingAndMonitoringAreReadyBeforeServiceStarts(rioFargateService) {
|
|
205
|
+
var _a;
|
|
206
|
+
rioFargateService.serviceContainerDefinition.addContainerDependencies({
|
|
207
|
+
container: rioFargateService.datadogSideCarContainerDefinition,
|
|
208
|
+
condition: ecs.ContainerDependencyCondition.HEALTHY,
|
|
209
|
+
});
|
|
210
|
+
if (rioFargateService.logRouterContainerDefinition) {
|
|
211
|
+
rioFargateService.serviceContainerDefinition.addContainerDependencies({
|
|
212
|
+
container: rioFargateService.logRouterContainerDefinition,
|
|
213
|
+
condition: ecs.ContainerDependencyCondition.START,
|
|
214
|
+
});
|
|
215
|
+
if (((_a = rioFargateService.datadogSideCarContainerDefinition.logDriverConfig) === null || _a === void 0 ? void 0 : _a.logDriver) === 'awsfirelens') {
|
|
216
|
+
rioFargateService.datadogSideCarContainerDefinition.addContainerDependencies({
|
|
217
|
+
container: rioFargateService.logRouterContainerDefinition,
|
|
218
|
+
condition: ecs.ContainerDependencyCondition.START,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
exports.DataDog = DataDog;
|
|
225
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YWRvZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9mYXJnYXRlL2RhdGFkb2cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkNBQWtEO0FBQ2xELDJDQUEyQztBQUMzQyxpREFBaUQ7QUFDakQsNkNBQTZDO0FBRzdDLCtEQUE4RTtBQUU5RSxNQUFhLE9BQU87SUFFWCxNQUFNLENBQUMsdUNBQXVDLENBQ25ELEtBQWdCLEVBQ2hCLEtBQWEsRUFDYixXQUFtQixFQUNuQixPQUFlLEVBQ2YsV0FBbUIsRUFDbkIsUUFBZ0I7UUFHaEIsTUFBTSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLEdBQUcsbUJBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFdkQsT0FBTztZQUNMLDJHQUEyRztZQUMzRyxNQUFNLEVBQUUsS0FBSztZQUNiLFVBQVUsRUFBRSxXQUFXO1lBQ3ZCLFVBQVUsRUFBRSxPQUFPO1lBQ25CLG9HQUFvRztZQUNwRyxpQkFBaUIsRUFBRSxNQUFNO1lBQ3pCLGtCQUFrQixFQUFFLElBQUksQ0FBQyw0Q0FBNEMsQ0FBQyxXQUFXLENBQUM7WUFDbEYsT0FBTyxFQUFFLElBQUksQ0FBQywrQkFBK0IsQ0FDM0MsU0FBUyxFQUNULFdBQVcsRUFDWCxNQUFNLEVBQ04sUUFBUSxFQUNSLEtBQUssRUFDTCxXQUFXLEVBQ1gsT0FBTyxFQUNQLFNBQVMsQ0FDVjtZQUNELG9CQUFvQixFQUFFLEtBQUs7U0FDNUIsQ0FBQztJQUNKLENBQUM7SUFFRCxrSEFBa0g7SUFDbEgsTUFBTSxDQUFDLDRDQUE0QyxDQUFDLFdBQW1CO1FBRXJFLE1BQU0sY0FBYyxHQUFHO1lBQ3JCLFVBQVUsRUFBRSxHQUFHLFdBQVcsU0FBUztZQUNuQyxjQUFjLEVBQUUsR0FBRyxXQUFXLFVBQVU7WUFDeEMsT0FBTyxFQUFFLEdBQUcsV0FBVyxRQUFRO1lBQy9CLE9BQU8sRUFBRSxHQUFHLFdBQVcsU0FBUztZ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QkFBaUIsQ0FBQyw0QkFBNEIsRUFBRTtZQUNsRCxpQkFBaUIsQ0FBQywwQkFBMEIsQ0FBQyx3QkFBd0IsQ0FBQztnQkFDcEUsU0FBUyxFQUFFLGlCQUFpQixDQUFDLDRCQUE0QjtnQkFDekQsU0FBUyxFQUFFLEdBQUcsQ0FBQyw0QkFBNEIsQ0FBQyxLQUFLO2FBQ2xELENBQUMsQ0FBQztZQUVILElBQUksT0FBQSxpQkFBaUIsQ0FBQyxpQ0FBaUMsQ0FBQyxlQUFlLDBDQUFFLFNBQVMsTUFBSyxhQUFhLEVBQUU7Z0JBQ3BHLGlCQUFpQixDQUFDLGlDQUFpQyxDQUFDLHdCQUF3QixDQUFDO29CQUMzRSxTQUFTLEVBQUUsaUJBQWlCLENBQUMsNEJBQTRCO29CQUN6RCxTQUFTLEVBQUUsR0FBRyxDQUFDLDRCQUE0QixDQUFDLEtBQUs7aUJBQ2xELENBQUMsQ0FBQzthQUNKO1NBQ0Y7SUFDSCxDQUFDO0NBQ0Y7QUFqVkQsMEJBaVZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU3RhY2ssIER1cmF0aW9uLCBGbiB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGVjcyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWNzJztcbmltcG9ydCAqIGFzIGxhbWJkYSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCAqIGFzIGxvZ3MgZnJvbSAnYXdzLWNkay1saWIvYXdzLWxvZ3MnO1xuaW1wb3J0ICogYXMgc3NtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zc20nO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBEYXRhRG9nTG9nZ2luZ01vZGUsIFJpb0ZhcmdhdGVTZXJ2aWNlIH0gZnJvbSAnLi9yaW8tZmFyZ2F0ZS1zZXJ2aWNlJztcblxuZXhwb3J0IGNsYXNzIERhdGFEb2cge1xuXG4gIHB1YmxpYyBzdGF0aWMgZ2V0RmFyZ2F0ZUNvbnRhaW5lckVudmlyb25tZW50VmFyaWFibGVzKFxuICAgIHNjb3BlOiBDb25zdHJ1Y3QsXG4gICAgc3RhZ2U6IHN0cmluZyxcbiAgICBzZXJ2aWNlTmFtZTogc3RyaW5nLFxuICAgIHZlcnNpb246IHN0cmluZyxcbiAgICBhY2NvdW50TmFtZTogc3RyaW5nLFxuICAgIHRlYW1OYW1lOiBzdHJpbmcsXG4gICk6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0ge1xuXG4gICAgY29uc3QgeyBhY2NvdW50OiBhY2NvdW50SWQsIHJlZ2lvbiB9ID0gU3RhY2sub2Yoc2NvcGUpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC8vIHVuaWZpZWQgdGFnZ2luZywgc2VlIGh0dHBzOi8vZG9jcy5kYXRhZG9naHEuY29tL2dldHRpbmdfc3RhcnRlZC90YWdnaW5nL3VuaWZpZWRfc2VydmljZV90YWdnaW5nLz90YWI9ZWNzXG4gICAgICBERF9FTlY6IHN0YWdlLFxuICAgICAgRERfU0VSVklDRTogc2VydmljZU5hbWUsXG4gICAgICBERF9WRVJTSU9OOiB2ZXJzaW9uLFxuICAgICAgLy8gQVBNIGFuZCB0cmFjaW5nLCBzZWUgaHR0cHM6Ly9kb2NzLmRhdGFkb2docS5jb20vdHJhY2luZy9zZXR1cF9vdmVydmlldy9zZXR1cC9qYXZhLz90YWI9Y29udGFpbmVyc1xuICAgICAgRERfTE9HU19JTkpFQ1RJT046ICd0cnVlJyxcbiAgICAgIEREX1NFUlZJQ0VfTUFQUElORzogdGhpcy5nZXRBcG1TZXJ2aWNlTWFwcGluZ0Vudmlyb25tZW50VmFyaWFibGVWYWx1ZShzZXJ2aWNlTmFtZSksXG4gICAgICBERF9UQUdTOiB0aGlzLmdldFRhZ3NFbnZpcm9ubWVudFZhcmlhYmxlVmFsdWUoXG4gICAgICAgIGFjY291bnRJZCxcbiAgICAgICAgYWNjb3VudE5hbWUsXG4gICAgICAgIHJlZ2lvbixcbiAgICAgICAgdGVhbU5hbWUsXG4gICAgICAgIHN0YWdlLFxuICAgICAgICBzZXJ2aWNlTmFtZSxcbiAgICAgICAgdmVyc2lvbixcbiAgICAgICAgJ3NlcnZpY2UnLFxuICAgICAgKSxcbiAgICAgIEREX1RSQUNFX1NBTVBMRV9SQVRFOiAnMS4wJywgLy8gc2VlIGh0dHBzOi8vZGR0cmFjZS5yZWFkdGhlZG9jcy5pby9lbi9zdGFibGUvY29uZmlndXJhdGlvbi5odG1sXG4gICAgfTtcbiAgfVxuXG4gIC8vIHdlIGFkZCBhbGwgcG9zc2libGUgc2VydmljZSBtYXBwaW5ncyBoZXJlIGV2ZW4gaWYgbm90IHVzZWQgaW4gYSBwYXJ0aWN1bGFyIHNlcnZpY2UgdG8gZ2V0IGdsb2JhbGx5IHVuaXF1ZSBuYW1lc1xuICBzdGF0aWMgZ2V0QXBtU2VydmljZU1hcHBpbmdFbnZpcm9ubWVudFZhcmlhYmxlVmFsdWUoc2VydmljZU5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG5cbiAgICBjb25zdCBzZXJ2aWNlTWFwcGluZyA9IHtcbiAgICAgICdkYXRhYmFzZSc6IGAke3NlcnZpY2VOYW1lfS1hdXJvcmFgLFxuICAgICAgJ2phdmEtYXdzLXNkayc6IGAke3NlcnZpY2VOYW1lfS1hd3Mtc2RrYCxcbiAgICAgICdrYWZrYSc6IGAke3NlcnZpY2VOYW1lfS1rYWZrYWAsXG4gICAgICAnbXlzcWwnOiBgJHtzZXJ2aWNlTmFtZX0tYXVyb3JhYCxcbiAgICAgICdyZWRpcyc6IGAke3NlcnZpY2VOYW1lfS1yZWRpc2AsXG4gICAgfTtcblxuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhzZXJ2aWNlTWFwcGluZylcbiAgICAgIC5tYXAoKFtrZXksIHZhbHVlXSkgPT4gYCR7a2V5fToke3ZhbHVlfWApXG4gICAgICAuam9pbignLCcpO1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyBnZXRGYXJnYXRlRG9ja2VyTGFiZWxzKHN0YWdlOiBzdHJpbmcsIHNlcnZpY2VOYW1lOiBzdHJpbmcsIHZlcnNpb246IHN0cmluZyk6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0ge1xuICAgIHJldHVybiB7XG4gICAgICAnY29tLmRhdGFkb2docS50YWdzLmVudic6IHN0YWdlLFxuICAgICAgJ2NvbS5kYXRhZG9naHEudGFncy5zZXJ2aWNlJzogc2VydmljZU5hbWUsXG4gICAgICAnY29tLmRhdGFkb2docS50YWdzLnZlcnNpb24nOiB2ZXJzaW9uLFxuICAgIH07XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGFkZERhdGFkb2dTaWRlY2FyKFxuICAgIHNjb3BlOiBDb25zdHJ1Y3QsXG4gICAgdGFza0RlZmluaXRpb246IGVjcy5UYXNrRGVmaW5pdGlvbixcbiAgICBhY2NvdW50TmFtZTogc3RyaW5nLFxuICAgIHRlYW1OYW1lOiBzdHJpbmcsXG4gICAgc3RhZ2U6IHN0cmluZyxcbiAgICBzZXJ2aWNlTmFtZTogc3RyaW5nLFxuICAgIHZlcnNpb246IHN0cmluZyxcbiAgICBkYXRhZG9nQXBpS2V5UGFyYW1ldGVyOiBzc20uSVN0cmluZ1BhcmFtZXRlcixcbiAgICBkYXRhZG9nU2l0ZTogc3RyaW5nLFxuICAgIGRhdGFkb2dMb2dnaW5nTW9kZTogRGF0YURvZ0xvZ2dpbmdNb2RlLFxuICAgIGFwbUdldFJlc291cmNlc1RvSWdub3JlOiBzdHJpbmdbXSxcbiAgICBjcHU6IG51bWJlcixcbiAgICBtZW1vcnlMaW1pdE1pQjogbnVtYmVyLFxuICAgIGVzc2VudGlhbDogYm9vbGVhbixcbiAgICBjb250YWluZXJUYWc6IHN0cmluZyxcbiAgKTogZWNzLkNvbnRhaW5lckRlZmluaXRpb24ge1xuXG4gICAgY29uc3QgeyBhY2NvdW50OiBhY2NvdW50SWQsIHJlZ2lvbiB9ID0gU3RhY2sub2Yoc2NvcGUpO1xuICAgIGNvbnN0IGRhdGFkb2dTaWRlY2FyID0gdGFza0RlZmluaXRpb24uYWRkQ29udGFpbmVyKCdkYXRhZG9nLWFnZW50Jywge1xuICAgICAgaW1hZ2U6IGVjcy5Db250YWluZXJJbWFnZS5mcm9tUmVnaXN0cnkoYHB1YmxpYy5lY3IuYXdzL2RhdGFkb2cvYWdlbnQ6JHtjb250YWluZXJUYWd9YCksXG4gICAgICBsb2dnaW5nOiB0aGlzLnNldHVwTG9nZ2luZyhcbiAgICAgICAgc2NvcGUsXG4gICAgICAgIGFjY291bnROYW1lLFxuICAgICAgICB0ZWFtTmFtZSxcbiAgICAgICAgc3RhZ2UsXG4gICAgICAgIHNlcnZpY2VOYW1lLFxuICAgICAgICB2ZXJzaW9uLFxuICAgICAgICBkYXRhZG9nQXBpS2V5UGFyYW1ldGVyLFxuICAgICAgICBkYXRhZG9nTG9nZ2luZ01vZGUsXG4gICAgICAgIGRhdGFkb2dTaXRlLFxuICAgICAgICAnZGF0YWRvZy1zaWRlY2FyJyxcbiAgICAgICksXG4gICAgICBjcHUsXG4gICAgICBtZW1vcnlMaW1pdE1pQixcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIC8vIHVuaWZpZWQgdGFnZ2luZywgc2VlIGh0dHBzOi8vZG9jcy5kYXRhZG9naHEuY29tL2dldHRpbmdfc3RhcnRlZC90YWdnaW5nL3VuaWZpZWRfc2VydmljZV90YWdnaW5nLz90YWI9ZWNzXG4gICAgICAgIEREX0VOVjogc3RhZ2UsXG4gICAgICAgIEREX1NFUlZJQ0U6IHNlcnZpY2VOYW1lLFxuICAgICAgICBERF9WRVJTSU9OOiB2ZXJzaW9uLFxuICAgICAgICAvLyBBUE0gYW5kIHRyYWNpbmcgc2VlIGh0dHBzOi8vZG9jcy5kYXRhZG9naHEuY29tL2FnZW50L2RvY2tlci9hcG0vP3RhYj1saW51eFxuICAgICAgICBERF9BUE1fRU5BQkxFRDogJ3RydWUnLFxuICAgICAgICBERF9BUE1fSUdOT1JFX1JFU09VUkNFUzogYXBtR2V0UmVzb3VyY2VzVG9JZ25vcmVcbiAgICAgICAgICAubWFwKChhcG1HZXRSZXNvdXJjZVRvSWdub3JlKSA9PiBgR0VUICR7YXBtR2V0UmVzb3VyY2VUb0lnbm9yZX1gKVxuICAgICAgICAgIC5qb2luKCcsJyksXG4gICAgICAgIC8vIGdlbmVyYWwgc2V0dGluZ3NcbiAgICAgICAgRERfU0lURTogZGF0YWRvZ1NpdGUsXG4gICAgICAgIEREX1RBR1M6IHRoaXMuZ2V0VGFnc0Vudmlyb25tZW50VmFyaWFibGVWYWx1ZShcbiAgICAgICAgICBhY2NvdW50SWQsXG4gICAgICAgICAgYWNjb3VudE5hbWUsXG4gICAgICAgICAgcmVnaW9uLFxuICAgICAgICAgIHRlYW1OYW1lLFxuICAgICAgICAgIHN0YWdlLFxuICAgICAgICAgIHNlcnZpY2VOYW1lLFxuICAgICAgICAgIHZlcnNpb24sXG4gICAgICAgICAgJ2RhdGFkb2ctc2lkZWNhcicsXG4gICAgICAgICksXG4gICAgICAgIEVDU19GQVJHQVRFOiAndHJ1ZScsXG4gICAgICAgIEREX0NPTExFQ1RfR0NFX1RBR1M6ICdmYWxzZScsXG4gICAgICB9LFxuICAgICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9EYXRhRG9nL2RhdGFkb2ctYWdlbnQvYmxvYi9tYXN0ZXIvRG9ja2VyZmlsZXMvYWdlbnQvYW1kNjQvRG9ja2VyZmlsZSNMMTcxLUwxNzJcbiAgICAgIGhlYWx0aENoZWNrOiB7XG4gICAgICAgIHN0YXJ0UGVyaW9kOiBEdXJhdGlvbi5taW51dGVzKDIpLFxuICAgICAgICBpbnRlcnZhbDogRHVyYXRpb24uc2Vjb25kcygzMCksXG4gICAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLnNlY29uZHMoNSksXG4gICAgICAgIHJldHJpZXM6IDIsXG4gICAgICAgIGNvbW1hbmQ6IFsnQ01ELVNIRUxMJywgJy9wcm9iZS5zaCddLFxuICAgICAgfSxcbiAgICAgIHNlY3JldHM6IHtcbiAgICAgICAgRERfQVBJX0tFWTogZWNzLlNlY3JldC5mcm9tU3NtUGFyYW1ldGVyKGRhdGFkb2dBcGlLZXlQYXJhbWV0ZXIpLFxuICAgICAgfSxcbiAgICAgIGVzc2VudGlhbDogZXNzZW50aWFsLFxuICAgIH0pO1xuXG4gICAgZGF0YWRvZ1NpZGVjYXIuYWRkUG9ydE1hcHBpbmdzKHtcbiAgICAgIGNvbnRhaW5lclBvcnQ6IDgxMjUsXG4gICAgICBwcm90b2NvbDogZWNzLlByb3RvY29sLlVEUCxcbiAgICB9KTtcblxuICAgIGRhdGFkb2dTaWRlY2FyLmFkZFBvcnRNYXBwaW5ncyh7XG4gICAgICBjb250YWluZXJQb3J0OiA4MTI2LFxuICAgICAgcHJvdG9jb2w6IGVjcy5Qcm90b2NvbC5UQ1AsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gZGF0YWRvZ1NpZGVjYXI7XG4gIH1cblxuICBzdGF0aWMgZ2V0VGFnc0Vudmlyb25tZW50VmFyaWFibGVWYWx1ZShcbiAgICBhY2NvdW50SWQ6IHN0cmluZyxcbiAgICBhY2NvdW50TmFtZTogc3RyaW5nLFxuICAgIHJlZ2lvbjogc3RyaW5nLFxuICAgIHRlYW1OYW1lOiBzdHJpbmcsXG4gICAgc3RhZ2U6IHN0cmluZyxcbiAgICBzZXJ2aWNlTmFtZTogc3RyaW5nLFxuICAgIHZlcnNpb246IHN0cmluZyxcbiAgICBjb250YWluZXJUeXBlOiAnc2VydmljZScgfCAnZGF0YWRvZy1zaWRlY2FyJyB8ICdmbHVlbnQtYml0JyxcbiAgKTogc3RyaW5nIHtcblxuICAgIGxldCBzZXBhcmF0b3I6IHN0cmluZztcblxuICAgIHN3aXRjaCAoY29udGFpbmVyVHlwZSkge1xuXG4gICAgICBjYXNlICdzZXJ2aWNlJzpcbiAgICAgICAgc2VwYXJhdG9yID0gJywnO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnZGF0YWRvZy1zaWRlY2FyJzpcbiAgICAgICAgc2VwYXJhdG9yID0gJyAnO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnZmx1ZW50LWJpdCc6XG4gICAgICAgIHNlcGFyYXRvciA9ICcsJztcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgY29uc3QgdGFncyA9IHtcbiAgICAgIC8vIHVuaWZpZWQgdGFnZ2luZ1xuICAgICAgLy8gb3ZlcnJpZGRlbiBieSBkZWRpY2F0ZWQgc2V0dGluZ3MgKGVudmlyb25tZW50IHZhcmlhYmxlcy90YWdzKVxuICAgICAgLy8gZHVwbGljYXRlZCBoZXJlIHRvIGVuc3VyZSB0aGV5IGFyZSB1c2VkIChhbmQgc29tZXRpbWVzLCBub3QgYWxsIHRocmVlIHZhbHVlcyBhcmUgc3VwcG9ydGVkKVxuICAgICAgZW52OiBzdGFnZSxcbiAgICAgIHNlcnZpY2U6IHNlcnZpY2VOYW1lLFxuICAgICAgdmVyc2lvbixcbiAgICAgIC8vIGFjY291bnQvdGVhbSBzcGVjaWZpYyBwYXJ0c1xuICAgICAgYWNjb3VudF9pZDogYWNjb3VudElkLFxuICAgICAgYWNjb3VudF9uYW1lOiBhY2NvdW50TmFtZSxcbiAgICAgIHJlZ2lvbixcbiAgICAgIHRlYW06IHRlYW1OYW1lLFxuICAgIH07XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKHRhZ3MpXG4gICAgICAubWFwKChba2V5LCB2YWx1ZV0pID0+IGAke2tleX06JHt2YWx1ZX1gKVxuICAgICAgLmpvaW4oc2VwYXJhdG9yKTtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgYWRkRmlyZUxlbnNMb2dSb3V0ZXIoXG4gICAgdGFza0RlZmluaXRpb246IGVjcy5UYXNrRGVmaW5pdGlvbixcbiAgICBjcHU6IG51bWJlcixcbiAgICBtZW1vcnlMaW1pdE1pQjogbnVtYmVyLFxuICApOiBlY3MuQ29udGFpbmVyRGVmaW5pdGlvbiB7XG5cbiAgICByZXR1cm4gdGFza0RlZmluaXRpb24uYWRkRmlyZWxlbnNMb2dSb3V0ZXIoJ2ZpcmVsZW5zLWxvZy1yb3V0ZXInLCB7XG4gICAgICBpbWFnZTogZWNzLkNvbnRhaW5lckltYWdlLmZyb21SZWdpc3RyeSgncHVibGljLmVjci5hd3MvYXdzLW9ic2VydmFiaWxpdHkvYXdzLWZvci1mbHVlbnQtYml0OmxhdGVzdCcpLFxuICAgICAgZmlyZWxlbnNDb25maWc6IHtcbiAgICAgICAgdHlwZTogZWNzLkZpcmVsZW5zTG9nUm91dGVyVHlwZS5GTFVFTlRCSVQsXG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICBjb25maWdGaWxlVHlwZTogZWNzLkZpcmVsZW5zQ29uZmlnRmlsZVR5cGUuRklMRSxcbiAgICAgICAgICBjb25maWdGaWxlVmFsdWU6ICcvZmx1ZW50LWJpdC9jb25maWdzL3BhcnNlLWpzb24uY29uZicsXG4gICAgICAgICAgZW5hYmxlRUNTTG9nTWV0YWRhdGE6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgY3B1LFxuICAgICAgbWVtb3J5TGltaXRNaUIsXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIHNldHVwTG9nZ2luZyhcbiAgICBzY29wZTogQ29uc3RydWN0LFxuICAgIGFjY291bnROYW1lOiBzdHJpbmcsXG4gICAgdGVhbU5hbWU6IHN0cmluZyxcbiAgICBzdGFnZTogc3RyaW5nLFxuICAgIHNlcnZpY2VOYW1lOiBzdHJpbmcsXG4gICAgdmVyc2lvbjogc3RyaW5nLFxuICAgIGRhdGFkb2dBcGlLZXlQYXJhbWV0ZXI6IHNzbS5JU3RyaW5nUGFyYW1ldGVyLFxuICAgIGRhdGFkb2dMb2dnaW5nTW9kZTogRGF0YURvZ0xvZ2dpbmdNb2RlLFxuICAgIGRhdGFkb2dTaXRlOiBzdHJpbmcsXG4gICAgY29udGFpbmVyVHlwZTogJ3NlcnZpY2UnIHwgJ2RhdGFkb2ctc2lkZWNhcicsXG4gICk6IGVjcy5Mb2dEcml2ZXIge1xuXG4gICAgbGV0IGxvZ0dyb3VwTmFtZTogc3RyaW5nO1xuICAgIGxldCBsb2dHcm91cElkOiBzdHJpbmc7XG4gICAgbGV0IGNvbnRhaW5lclR5cGVDYW1lbENhc2U7XG5cbiAgICBzd2l0Y2ggKGNvbnRhaW5lclR5cGUpIHtcblxuICAgICAgY2FzZSAnc2VydmljZSc6XG4gICAgICAgIGxvZ0dyb3VwSWQgPSAnTG9nR3JvdXBGb3JTZXJ2aWNlJztcbiAgICAgICAgbG9nR3JvdXBOYW1lID0gc2VydmljZU5hbWU7XG4gICAgICAgIGNvbnRhaW5lclR5cGVDYW1lbENhc2UgPSAnU2VydmljZSc7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdkYXRhZG9nLXNpZGVjYXInOlxuICAgICAgICBsb2dHcm91cElkID0gJ0xvZ0dyb3VwRm9yRGF0YWRvZ1NpZGVjYXInO1xuICAgICAgICBsb2dHcm91cE5hbWUgPSBgJHtzZXJ2aWNlTmFtZX0tJHtjb250YWluZXJUeXBlfWA7XG4gICAgICAgIGNvbnRhaW5lclR5cGVDYW1lbENhc2UgPSAnRGF0YWRvZ1NpZGVjYXInO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBjb25zdCB7IGFjY291bnQ6IGFjY291bnRJZCwgcmVnaW9uIH0gPSBTdGFjay5vZihzY29wZSk7XG5cbiAgICBzd2l0Y2ggKGRhdGFkb2dMb2dnaW5nTW9kZSkge1xuXG4gICAgICBjYXNlIERhdGFEb2dMb2dnaW5nTW9kZS5BV1NfRklSRV9MRU5TOlxuICAgICAgICAvLyBUT0RPIGNhbiB3ZSB1c2UgYHNlY3JldE9wdGlvbnNgIGhlcmUgYXMgd2VsbCwgZS5nLiBhcyBpbiBodHRwczovL2dpdGh1Yi5jb20vYXdzLXNhbXBsZXMvYW1hem9uLWVjcy1maXJlbGVucy1leGFtcGxlcy9ibG9iL21haW5saW5lL2V4YW1wbGVzL2ZsdWVudC1iaXQvZGF0YWRvZy90YXNrLWRlZmluaXRpb24uanNvbiNMMzMtTDM2XG4gICAgICAgIC8vIFByb2JhYmx5IG5vdCwgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYXdzLWNkay9pc3N1ZXMvODE3NFxuICAgICAgICByZXR1cm4gZWNzLkxvZ0RyaXZlcnMuZmlyZWxlbnMoe1xuICAgICAgICAgIC8vIHNlZSBodHRwczovL2RvY3MuZGF0YWRvZ2hxLmNvbS9pbnRlZ3JhdGlvbnMvZmx1ZW50Yml0LyNjb25maWd1cmF0aW9uLXBhcmFtZXRlcnNcbiAgICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgICBOYW1lOiAnZGF0YWRvZycsXG4gICAgICAgICAgICBNYXRjaDogJyonLFxuICAgICAgICAgICAgSG9zdDogYGh0dHAtaW50YWtlLmxvZ3MuJHtkYXRhZG9nU2l0ZX1gLFxuICAgICAgICAgICAgVExTOiAnb24nLFxuICAgICAgICAgICAgYXBpa2V5OiBkYXRhZG9nQXBpS2V5UGFyYW1ldGVyLnN0cmluZ1ZhbHVlLFxuICAgICAgICAgICAgY29tcHJlc3M6ICdnemlwJyxcbiAgICAgICAgICAgIGRkX3NlcnZpY2U6IGxvZ0dyb3VwTmFtZSxcbiAgICAgICAgICAgIGRkX3NvdXJjZTogJ3Jpby1mYXJnYXRlJyxcbiAgICAgICAgICAgIGRkX21lc3NhZ2Vfa2V5OiAnbG9nJyxcbiAgICAgICAgICAgIGRkX3RhZ3M6IHRoaXMuZ2V0VGFnc0Vudmlyb25tZW50VmFyaWFibGVWYWx1ZShcbiAgICAgICAgICAgICAgYWNjb3VudElkLFxuICAgICAgICAgICAgICBhY2NvdW50TmFtZSxcbiAgICAgICAgICAgICAgcmVnaW9uLFxuICAgICAgICAgICAgICB0ZWFtTmFtZSxcbiAgICAgICAgICAgICAgc3RhZ2UsXG4gICAgICAgICAgICAgIHNlcnZpY2VOYW1lLFxuICAgICAgICAgICAgICB2ZXJzaW9uLFxuICAgICAgICAgICAgICAnZmx1ZW50LWJpdCcsXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgcHJvdmlkZXI6ICdlY3MnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICBjYXNlIERhdGFEb2dMb2dnaW5nTW9kZS5GT1JXQVJERVJfTEFNQkRBOlxuICAgICAgICBjb25zdCBsb2dHcm91cEZvckZvcndhcmRpbmdMYW1iZGEgPSBuZXcgbG9ncy5Mb2dHcm91cChzY29wZSwgbG9nR3JvdXBJZCwge1xuICAgICAgICAgIGxvZ0dyb3VwTmFtZSxcbiAgICAgICAgICByZXRlbnRpb246IGxvZ3MuUmV0ZW50aW9uRGF5cy5PTkVfV0VFSyxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGxvZ0ZvcndhcmRlckxhbWJkYUFybiA9IEZuLmltcG9ydFZhbHVlKCdjdXN0b20tcmVzb3VyY2UtZGF0YWRvZy1sb2dmb3J3YXJkZXItZnVuY3Rpb24tYXJuJyk7XG4gICAgICAgIGNvbnN0IGNmblBlcm1pc3Npb24gPSBuZXcgbGFtYmRhLkNmblBlcm1pc3Npb24oc2NvcGUsIGBMb2dGb3J3YXJkZXJQZXJtaXNzaW9uJHtjb250YWluZXJUeXBlQ2FtZWxDYXNlfWAsIHtcbiAgICAgICAgICBhY3Rpb246ICdsYW1iZGE6SW52b2tlRnVuY3Rpb24nLFxuICAgICAgICAgIGZ1bmN0aW9uTmFtZTogbG9nRm9yd2FyZGVyTGFtYmRhQXJuLFxuICAgICAgICAgIHByaW5jaXBhbDogYGxvZ3MuJHtyZWdpb259LmFtYXpvbmF3cy5jb21gLFxuICAgICAgICAgIHNvdXJjZUFybjogbG9nR3JvdXBGb3JGb3J3YXJkaW5nTGFtYmRhLmxvZ0dyb3VwQXJuLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY2ZuU3Vic2NyaXB0aW9uRmlsdGVyID0gbmV3IGxvZ3MuQ2ZuU3Vic2NyaXB0aW9uRmlsdGVyKFxuICAgICAgICAgIHNjb3BlLFxuICAgICAgICAgIGBMb2dGb3J3YXJkZXJTdWJzY3JpcHRpb25GaWx0ZXIke2NvbnRhaW5lclR5cGVDYW1lbENhc2V9YCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkZXN0aW5hdGlvbkFybjogbG9nRm9yd2FyZGVyTGFtYmRhQXJuLFxuICAgICAgICAgICAgZmlsdGVyUGF0dGVybjogJycsXG4gICAgICAgICAgICBsb2dHcm91cE5hbWU6IGxvZ0dyb3VwRm9yRm9yd2FyZGluZ0xhbWJkYS5sb2dHcm91cE5hbWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgICAgY2ZuU3Vic2NyaXB0aW9uRmlsdGVyLmFkZERlcGVuZHNPbihjZm5QZXJtaXNzaW9uKTtcbiAgICAgICAgcmV0dXJuIGVjcy5Mb2dEcml2ZXJzLmF3c0xvZ3Moe1xuICAgICAgICAgIHN0cmVhbVByZWZpeDogY29udGFpbmVyVHlwZSxcbiAgICAgICAgICBsb2dHcm91cDogbG9nR3JvdXBGb3JGb3J3YXJkaW5nTGFtYmRhLFxuICAgICAgICB9KTtcblxuICAgICAgY2FzZSBEYXRhRG9nTG9nZ2luZ01vZGUuTk9ORTpcbiAgICAgICAgY29uc3QgbG9nR3JvdXBJbkNsb3Vkd2F0Y2hPbmx5ID0gbmV3IGxvZ3MuTG9nR3JvdXAoc2NvcGUsIGxvZ0dyb3VwSWQsIHtcbiAgICAgICAgICByZXRlbnRpb246IGxvZ3MuUmV0ZW50aW9uRGF5cy5PTkVfV0VFSyxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBlY3MuTG9nRHJpdmVycy5hd3NMb2dzKHtcbiAgICAgICAgICBzdHJlYW1QcmVmaXg6IGNvbnRhaW5lclR5cGUsXG4gICAgICAgICAgbG9nR3JvdXA6IGxvZ0dyb3VwSW5DbG91ZHdhdGNoT25seSxcbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHN0YXRpYyBlbnN1cmVMb2dnaW5nQW5kTW9uaXRvcmluZ0FyZVJlYWR5QmVmb3JlU2VydmljZVN0YXJ0cyhyaW9GYXJnYXRlU2VydmljZTogUmlvRmFyZ2F0ZVNlcnZpY2UpIHtcblxuICAgIHJpb0ZhcmdhdGVTZXJ2aWNlLnNlcnZpY2VDb250YWluZXJEZWZpbml0aW9uLmFkZENvbnRhaW5lckRlcGVuZGVuY2llcyh7XG4gICAgICBjb250YWluZXI6IHJpb0ZhcmdhdGVTZXJ2aWNlLmRhdGFkb2dTaWRlQ2FyQ29udGFpbmVyRGVmaW5pdGlvbixcbiAgICAgIGNvbmRpdGlvbjogZWNzLkNvbnRhaW5lckRlcGVuZGVuY3lDb25kaXRpb24uSEVBTFRIWSxcbiAgICB9KTtcblxuICAgIGlmIChyaW9GYXJnYXRlU2VydmljZS5sb2dSb3V0ZXJDb250YWluZXJEZWZpbml0aW9uKSB7XG4gICAgICByaW9GYXJnYXRlU2VydmljZS5zZXJ2aWNlQ29udGFpbmVyRGVmaW5pdGlvbi5hZGRDb250YWluZXJEZXBlbmRlbmNpZXMoe1xuICAgICAgICBjb250YWluZXI6IHJpb0ZhcmdhdGVTZXJ2aWNlLmxvZ1JvdXRlckNvbnRhaW5lckRlZmluaXRpb24sXG4gICAgICAgIGNvbmRpdGlvbjogZWNzLkNvbnRhaW5lckRlcGVuZGVuY3lDb25kaXRpb24uU1RBUlQsXG4gICAgICB9KTtcblxuICAgICAgaWYgKHJpb0ZhcmdhdGVTZXJ2aWNlLmRhdGFkb2dTaWRlQ2FyQ29udGFpbmVyRGVmaW5pdGlvbi5sb2dEcml2ZXJDb25maWc/LmxvZ0RyaXZlciA9PT0gJ2F3c2ZpcmVsZW5zJykge1xuICAgICAgICByaW9GYXJnYXRlU2VydmljZS5kYXRhZG9nU2lkZUNhckNvbnRhaW5lckRlZmluaXRpb24uYWRkQ29udGFpbmVyRGVwZW5kZW5jaWVzKHtcbiAgICAgICAgICBjb250YWluZXI6IHJpb0ZhcmdhdGVTZXJ2aWNlLmxvZ1JvdXRlckNvbnRhaW5lckRlZmluaXRpb24sXG4gICAgICAgICAgY29uZGl0aW9uOiBlY3MuQ29udGFpbmVyRGVwZW5kZW5jeUNvbmRpdGlvbi5TVEFSVCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbiJdfQ==
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { Duration } from 'aws-cdk-lib';
|
|
2
|
+
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
|
3
|
+
import * as ecs from 'aws-cdk-lib/aws-ecs';
|
|
4
|
+
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
|
|
5
|
+
import { Construct } from 'constructs';
|
|
6
|
+
/**
|
|
7
|
+
* Fargate Task Definition Properties.
|
|
8
|
+
*/
|
|
9
|
+
export interface RioFargateServiceProps {
|
|
10
|
+
/**
|
|
11
|
+
* The stage of the service, e.g. 'prod'.
|
|
12
|
+
*/
|
|
13
|
+
readonly stage: string;
|
|
14
|
+
/**
|
|
15
|
+
* The Name of the service.
|
|
16
|
+
*/
|
|
17
|
+
readonly serviceName: string;
|
|
18
|
+
/**
|
|
19
|
+
* The version of the service, e.g. the git hash of the corresponding commit.
|
|
20
|
+
*/
|
|
21
|
+
readonly version: string;
|
|
22
|
+
/**
|
|
23
|
+
* The frameworks in uses.
|
|
24
|
+
*
|
|
25
|
+
* @default - No frameworks.
|
|
26
|
+
*/
|
|
27
|
+
readonly frameworks?: Framework[];
|
|
28
|
+
/**
|
|
29
|
+
* The VPC of the service.
|
|
30
|
+
*/
|
|
31
|
+
readonly vpc: ec2.IVpc;
|
|
32
|
+
/**
|
|
33
|
+
* Container definition options like image, cpu, memory.
|
|
34
|
+
*/
|
|
35
|
+
readonly containerDefinitionOption: ContainerDefinitionOptions;
|
|
36
|
+
/**
|
|
37
|
+
* Fargate Task Definition Properties.
|
|
38
|
+
*/
|
|
39
|
+
readonly fargateOptions: FargateTaskDefinitionProps;
|
|
40
|
+
/**
|
|
41
|
+
* Loadbalancer options.
|
|
42
|
+
*/
|
|
43
|
+
readonly loadBalancerOptions?: LoadBalancerOptions;
|
|
44
|
+
/**
|
|
45
|
+
* Datadog integration properties
|
|
46
|
+
*/
|
|
47
|
+
readonly datadogOptions?: DatadogIntegrationProps;
|
|
48
|
+
}
|
|
49
|
+
export declare enum Framework {
|
|
50
|
+
/**
|
|
51
|
+
* Spring Framework, Spring Boot, and Spring Cloud AWS.
|
|
52
|
+
*/
|
|
53
|
+
SPRING = 0
|
|
54
|
+
}
|
|
55
|
+
export interface ContainerDefinitionOptions {
|
|
56
|
+
/**
|
|
57
|
+
* The image used to start a container.
|
|
58
|
+
*
|
|
59
|
+
* This string is passed directly to the Docker daemon.
|
|
60
|
+
* Images in the Docker Hub registry are available by default.
|
|
61
|
+
* Other repositories are specified with either repository-url/image:tag or repository-url/image@digest.
|
|
62
|
+
*/
|
|
63
|
+
readonly image: ecs.ContainerImage;
|
|
64
|
+
/**
|
|
65
|
+
* The environment variables to pass to the container.
|
|
66
|
+
*
|
|
67
|
+
* Environment variables set by default are overwritten if passed.
|
|
68
|
+
*
|
|
69
|
+
* The default environment variables set are
|
|
70
|
+
*
|
|
71
|
+
* DD_ENV: Set same as prop stage
|
|
72
|
+
*
|
|
73
|
+
* DD_SERVICE: Set same as prop serviceName
|
|
74
|
+
*
|
|
75
|
+
* DD_VERSION: Set same as prop version
|
|
76
|
+
*
|
|
77
|
+
* DD_LOGS_INJECTION: true
|
|
78
|
+
*
|
|
79
|
+
* DD_SERVICE_MAPPING: database:fargate-web-app-aurora,java-aws-sdk:fargate-web-app-aws-sdk,kafka:fargate-web-app-kafka,mysql:fargate-web-app-aurora
|
|
80
|
+
*
|
|
81
|
+
* DD_TAGS: env:prod,service:fargate-web-app,version:notag,account_id:${accountID},account_name:${accountName},region:${AWSRegion},team:${teamName from ssm param /config/team/name}
|
|
82
|
+
*
|
|
83
|
+
* DD_TRACE_SAMPLE_RATE: 1.0
|
|
84
|
+
*
|
|
85
|
+
* @default - No environment variables.
|
|
86
|
+
*/
|
|
87
|
+
readonly environment?: {
|
|
88
|
+
[key: string]: string;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* The secret environment variables to pass to the container.
|
|
92
|
+
*
|
|
93
|
+
* @default - No secret environment variables.
|
|
94
|
+
*/
|
|
95
|
+
readonly secrets?: {
|
|
96
|
+
[key: string]: ecs.Secret;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* The health check command and associated configuration parameters for the container.
|
|
100
|
+
*
|
|
101
|
+
* @default - Health check configuration from container.
|
|
102
|
+
*/
|
|
103
|
+
readonly healthCheck?: ecs.HealthCheck;
|
|
104
|
+
}
|
|
105
|
+
export interface FargateTaskDefinitionProps {
|
|
106
|
+
/**
|
|
107
|
+
* The number of cpu units used by the task. For tasks using the Fargate launch type,
|
|
108
|
+
* this field is required and you must use one of the following values,
|
|
109
|
+
* which determines your range of valid values for the memory parameter:
|
|
110
|
+
*
|
|
111
|
+
* 256 (.25 vCPU) - Available memory values: 512 (0.5 GB), 1024 (1 GB), 2048 (2 GB)
|
|
112
|
+
*
|
|
113
|
+
* 512 (.5 vCPU) - Available memory values: 1024 (1 GB), 2048 (2 GB), 3072 (3 GB), 4096 (4 GB)
|
|
114
|
+
*
|
|
115
|
+
* 1024 (1 vCPU) - Available memory values: 2048 (2 GB), 3072 (3 GB), 4096 (4 GB), 5120 (5 GB), 6144 (6 GB), 7168 (7 GB), 8192 (8 GB)
|
|
116
|
+
*
|
|
117
|
+
* 2048 (2 vCPU) - Available memory values: Between 4096 (4 GB) and 16384 (16 GB) in increments of 1024 (1 GB)
|
|
118
|
+
*
|
|
119
|
+
* 4096 (4 vCPU) - Available memory values: Between 8192 (8 GB) and 30720 (30 GB) in increments of 1024 (1 GB)
|
|
120
|
+
*
|
|
121
|
+
* @default 512
|
|
122
|
+
*/
|
|
123
|
+
readonly cpu: number;
|
|
124
|
+
/**
|
|
125
|
+
* The amount (in MiB) of memory used by the task. For tasks using the Fargate launch type,
|
|
126
|
+
* this field is required and you must use one of the following values, which determines your range of valid values for the cpu parameter:
|
|
127
|
+
*
|
|
128
|
+
* 512 (0.5 GB), 1024 (1 GB), 2048 (2 GB) - Available cpu values: 256 (.25 vCPU)
|
|
129
|
+
*
|
|
130
|
+
* 1024 (1 GB), 2048 (2 GB), 3072 (3 GB), 4096 (4 GB) - Available cpu values: 512 (.5 vCPU)
|
|
131
|
+
*
|
|
132
|
+
* 2048 (2 GB), 3072 (3 GB), 4096 (4 GB), 5120 (5 GB), 6144 (6 GB), 7168 (7 GB), 8192 (8 GB) - Available cpu values: 1024 (1 vCPU)
|
|
133
|
+
*
|
|
134
|
+
* Between 4096 (4 GB) and 16384 (16 GB) in increments of 1024 (1 GB) - Available cpu values: 2048 (2 vCPU)
|
|
135
|
+
*
|
|
136
|
+
* Between 8192 (8 GB) and 30720 (30 GB) in increments of 1024 (1 GB) - Available cpu values: 4096 (4 vCPU)
|
|
137
|
+
*
|
|
138
|
+
* @default 1024
|
|
139
|
+
*/
|
|
140
|
+
readonly memoryLimitMiB: number;
|
|
141
|
+
/**
|
|
142
|
+
* Desired count of running tasks
|
|
143
|
+
*
|
|
144
|
+
* @default - When creating the service, default is 1; when updating the service, default uses
|
|
145
|
+
* the current task number.
|
|
146
|
+
*/
|
|
147
|
+
readonly desiredCount?: number;
|
|
148
|
+
}
|
|
149
|
+
export interface ListenerRule {
|
|
150
|
+
readonly priority: number;
|
|
151
|
+
readonly conditions: elbv2.ListenerCondition[];
|
|
152
|
+
}
|
|
153
|
+
export interface LoadBalancerOptions {
|
|
154
|
+
/**
|
|
155
|
+
* Listener for an Application Load Balancer
|
|
156
|
+
*/
|
|
157
|
+
readonly listener: elbv2.IApplicationListener;
|
|
158
|
+
/**
|
|
159
|
+
* One or more path patterns to compare against the request URL.
|
|
160
|
+
* The maximum size of each string is 128 characters.
|
|
161
|
+
* The comparison is case sensitive.
|
|
162
|
+
* The following wildcard characters are supported: * (matches 0 or more characters) and ? (matches exactly 1 character).
|
|
163
|
+
*
|
|
164
|
+
* Update requires: No interruption
|
|
165
|
+
*/
|
|
166
|
+
readonly listenerRules: ListenerRule[];
|
|
167
|
+
/**
|
|
168
|
+
* Health check options.
|
|
169
|
+
*/
|
|
170
|
+
readonly healthCheck: elbv2.HealthCheck;
|
|
171
|
+
/**
|
|
172
|
+
* Health check grace period.
|
|
173
|
+
*/
|
|
174
|
+
readonly healthCheckGracePeriod: Duration;
|
|
175
|
+
/**
|
|
176
|
+
* The time period during which the load balancer sends a newly registered target a linearly increasing share of the traffic to the target group.
|
|
177
|
+
|
|
178
|
+
*The range is 30-900 seconds (15 minutes).
|
|
179
|
+
|
|
180
|
+
* @default undefined
|
|
181
|
+
*/
|
|
182
|
+
readonly slowStart?: Duration;
|
|
183
|
+
/**
|
|
184
|
+
* The amount of time for Elastic Load Balancing to wait before deregistering a target.
|
|
185
|
+
|
|
186
|
+
* The range is 0-3600 seconds.
|
|
187
|
+
|
|
188
|
+
* @default 5
|
|
189
|
+
*/
|
|
190
|
+
readonly deregistrationDelay?: Duration;
|
|
191
|
+
}
|
|
192
|
+
export interface DatadogIntegrationProps {
|
|
193
|
+
/**
|
|
194
|
+
* The minimum number of CPU units to reserve for the container.
|
|
195
|
+
*
|
|
196
|
+
* @default - 64
|
|
197
|
+
*/
|
|
198
|
+
readonly cpu?: number;
|
|
199
|
+
/**
|
|
200
|
+
* The amount (in MiB) of memory to present to the container.
|
|
201
|
+
*
|
|
202
|
+
* If your container attempts to exceed the allocated memory, the container
|
|
203
|
+
* is terminated.
|
|
204
|
+
*
|
|
205
|
+
* At least one of memoryLimitMiB and memoryReservationMiB is required for non-Fargate services.
|
|
206
|
+
*
|
|
207
|
+
* @default - 128
|
|
208
|
+
*/
|
|
209
|
+
readonly memoryLimitMiB?: number;
|
|
210
|
+
/**
|
|
211
|
+
* The logging mode for the service.
|
|
212
|
+
*
|
|
213
|
+
* @default - Using the Datadog log forwarder lambda provided by the datadog-integration.
|
|
214
|
+
*/
|
|
215
|
+
readonly loggingModeForService?: DataDogLoggingMode;
|
|
216
|
+
/**
|
|
217
|
+
* The logging mode for the Datadog agent sidecar.
|
|
218
|
+
*
|
|
219
|
+
* @default - No logs in Datadog, Cloudwatch only.
|
|
220
|
+
*/
|
|
221
|
+
readonly loggingModeForDatadogAgent?: DataDogLoggingMode;
|
|
222
|
+
/**
|
|
223
|
+
* GET endpoints to ignore in Datadog's APM overview. This is useful to filter out all health check calls.
|
|
224
|
+
|
|
225
|
+
* @default - No endpoints are ignored.
|
|
226
|
+
*/
|
|
227
|
+
readonly apmGetEndpointsToIgnore?: string[];
|
|
228
|
+
/**
|
|
229
|
+
* Configure if the Datadog agent sidecar is marked as essential.
|
|
230
|
+
*
|
|
231
|
+
* @default - true.
|
|
232
|
+
*/
|
|
233
|
+
readonly datadogSidecarEssential?: boolean;
|
|
234
|
+
/**
|
|
235
|
+
* Configures the docker image tag for datadog sidecar
|
|
236
|
+
* @default - 'latest'
|
|
237
|
+
*/
|
|
238
|
+
readonly datadogSidecarTag?: string;
|
|
239
|
+
}
|
|
240
|
+
export declare enum DataDogLoggingMode {
|
|
241
|
+
/**
|
|
242
|
+
* Forward logs directly to Datadog using AWS FireLens as log router,
|
|
243
|
+
* see https://docs.datadoghq.com/integrations/ecs_fargate/?tab=fluentbitandfirelens#log-collection.
|
|
244
|
+
*/
|
|
245
|
+
AWS_FIRE_LENS = 0,
|
|
246
|
+
/**
|
|
247
|
+
* Store logs in AWS Cloudwatch and use the Datadog log forwarder lambda to forward the logs to Datadog,
|
|
248
|
+
* see https://docs.datadoghq.com/integrations/ecs_fargate/?tab=logdriver#log-collection.
|
|
249
|
+
*/
|
|
250
|
+
FORWARDER_LAMBDA = 1,
|
|
251
|
+
/**
|
|
252
|
+
* Only log to AWS Cloudwatch without forwarding the logs to Datadog.
|
|
253
|
+
*/
|
|
254
|
+
NONE = 2
|
|
255
|
+
}
|
|
256
|
+
export declare class RioFargateService extends Construct implements ec2.IConnectable {
|
|
257
|
+
private readonly DEFAULT_APM_GET_ENDPOINTS_TO_IGNORE;
|
|
258
|
+
private readonly DEFAULT_DATADOG_SIDECAR_CPU;
|
|
259
|
+
private readonly DEFAULT_DATADOG_SIDECAR_MEMORY_LIMIT_MIB;
|
|
260
|
+
private readonly DEFAULT_DATADOG_SIDECAR_ESSENTIAL;
|
|
261
|
+
private readonly DEFAULT_LOGGING_MODE_FOR_SERVICE;
|
|
262
|
+
private readonly DEFAULT_LOGGING_MODE_FOR_DATADOG_SIDECAR;
|
|
263
|
+
private readonly DEFAULT_DEREGISTRATION_DELAY;
|
|
264
|
+
private readonly DEFAULT_SLOW_START;
|
|
265
|
+
private readonly DEFAULT_DATADOG_SIDECAR_TAG;
|
|
266
|
+
private readonly LOG_ROUTER_CPU;
|
|
267
|
+
private readonly LOG_ROUTER_MEMORY_LIMIT_MIB;
|
|
268
|
+
readonly serviceContainerDefinition: ecs.ContainerDefinition;
|
|
269
|
+
readonly datadogSideCarContainerDefinition: ecs.ContainerDefinition;
|
|
270
|
+
readonly logRouterContainerDefinition?: ecs.ContainerDefinition;
|
|
271
|
+
readonly taskDefinition: ecs.FargateTaskDefinition;
|
|
272
|
+
readonly connections: ec2.Connections;
|
|
273
|
+
readonly service: ecs.FargateService;
|
|
274
|
+
readonly targetGroup: elbv2.ApplicationTargetGroup | undefined;
|
|
275
|
+
constructor(scope: Construct, id: string, props: RioFargateServiceProps);
|
|
276
|
+
}
|