@liflig/cdk 3.12.1 → 3.13.1
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.
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
## Validate using https://www.otelbin.io/#distro=adot%7E&distroVersion=v0.43.1%7E .
|
|
2
|
+
##
|
|
3
|
+
## Original copyright is Apache 2.0 to AWS (aws-observability on GitHub).
|
|
4
|
+
## https://github.com/aws-observability/aws-otel-collector/blob/14833d4af543da709c77cf9dc6827351dbd529b1/config/ecs/container-insights/otel-task-metrics-config.yaml
|
|
5
|
+
##
|
|
6
|
+
## This is a modified version of `./etc/ecs/container-insights/otel-task-metrics-config.yaml`
|
|
7
|
+
## where we add `resource_to_telemetry_conversion` so the otel resource `service.name`
|
|
8
|
+
## can be added to the metric. This is useful because you can filter in metrics based on service,
|
|
9
|
+
## instead of grouping e.g. all services' memory usage under the same metric.
|
|
10
|
+
##
|
|
11
|
+
## Search for `# THIS IS WHAT LIFLIG ADDED` to find our modifications.
|
|
12
|
+
##
|
|
13
|
+
##
|
|
14
|
+
## @see https://aws-otel.github.io/docs/setup/ecs/config-through-ssm
|
|
15
|
+
extensions:
|
|
16
|
+
health_check:
|
|
17
|
+
|
|
18
|
+
## These ports are also set in `taskDefinition.defaultContainer` as
|
|
19
|
+
## `OTEL_EXPORTER_OTLP_ENDPOINT` and so on.
|
|
20
|
+
## Changes must happen in both places.
|
|
21
|
+
receivers:
|
|
22
|
+
otlp:
|
|
23
|
+
protocols:
|
|
24
|
+
grpc:
|
|
25
|
+
endpoint: 0.0.0.0:4317
|
|
26
|
+
http:
|
|
27
|
+
endpoint: 0.0.0.0:4318
|
|
28
|
+
awsxray:
|
|
29
|
+
endpoint: 0.0.0.0:2000
|
|
30
|
+
transport: udp
|
|
31
|
+
awsecscontainermetrics:
|
|
32
|
+
|
|
33
|
+
processors:
|
|
34
|
+
batch/traces:
|
|
35
|
+
timeout: 1s
|
|
36
|
+
send_batch_size: 50
|
|
37
|
+
batch/metrics:
|
|
38
|
+
timeout: 60s
|
|
39
|
+
filter:
|
|
40
|
+
metrics:
|
|
41
|
+
include:
|
|
42
|
+
match_type: strict
|
|
43
|
+
metric_names:
|
|
44
|
+
- ecs.task.memory.reserved
|
|
45
|
+
- ecs.task.memory.utilized
|
|
46
|
+
- ecs.task.cpu.reserved
|
|
47
|
+
- ecs.task.cpu.utilized
|
|
48
|
+
- ecs.task.network.rate.rx
|
|
49
|
+
- ecs.task.network.rate.tx
|
|
50
|
+
- ecs.task.storage.read_bytes
|
|
51
|
+
- ecs.task.storage.write_bytes
|
|
52
|
+
- container.duration
|
|
53
|
+
metricstransform:
|
|
54
|
+
transforms:
|
|
55
|
+
- include: ecs.task.memory.utilized
|
|
56
|
+
action: update
|
|
57
|
+
new_name: MemoryUtilized
|
|
58
|
+
- include: ecs.task.memory.reserved
|
|
59
|
+
action: update
|
|
60
|
+
new_name: MemoryReserved
|
|
61
|
+
- include: ecs.task.cpu.utilized
|
|
62
|
+
action: update
|
|
63
|
+
new_name: CpuUtilized
|
|
64
|
+
- include: ecs.task.cpu.reserved
|
|
65
|
+
action: update
|
|
66
|
+
new_name: CpuReserved
|
|
67
|
+
- include: ecs.task.network.rate.rx
|
|
68
|
+
action: update
|
|
69
|
+
new_name: NetworkRxBytes
|
|
70
|
+
- include: ecs.task.network.rate.tx
|
|
71
|
+
action: update
|
|
72
|
+
new_name: NetworkTxBytes
|
|
73
|
+
- include: ecs.task.storage.read_bytes
|
|
74
|
+
action: update
|
|
75
|
+
new_name: StorageReadBytes
|
|
76
|
+
- include: ecs.task.storage.write_bytes
|
|
77
|
+
action: update
|
|
78
|
+
new_name: StorageWriteBytes
|
|
79
|
+
## THIS IS WHAT LIFLIG ADDED
|
|
80
|
+
filter/application:
|
|
81
|
+
error_mode: ignore
|
|
82
|
+
metrics:
|
|
83
|
+
metric:
|
|
84
|
+
- 'resource.attributes["http.target"] == "/health"'
|
|
85
|
+
- 'resource.attributes["net.peer.name"] == "169.254.170.2"' # EC2 Metadata Endpoint
|
|
86
|
+
filter/traces:
|
|
87
|
+
error_mode: ignore
|
|
88
|
+
traces:
|
|
89
|
+
span:
|
|
90
|
+
- 'attributes["http.route"] == "health"'
|
|
91
|
+
- 'attributes["http.url"] == "/health"'
|
|
92
|
+
- 'name == "GET health"'
|
|
93
|
+
attributes/application:
|
|
94
|
+
actions:
|
|
95
|
+
# Http adds lots of high cardinality, which xray creates 1 metric per. Expensive.
|
|
96
|
+
- key: http.url
|
|
97
|
+
action: delete
|
|
98
|
+
- key: http.target
|
|
99
|
+
action: delete
|
|
100
|
+
- key: http.client_ip
|
|
101
|
+
action: delete
|
|
102
|
+
- key: http.response_content_length
|
|
103
|
+
action: delete
|
|
104
|
+
- key: http.request_content_length
|
|
105
|
+
action: delete
|
|
106
|
+
- key: net.host.name
|
|
107
|
+
action: delete
|
|
108
|
+
- key: net.sock.peer.addr
|
|
109
|
+
action: delete
|
|
110
|
+
- key: net.sock.peer.port
|
|
111
|
+
action: delete
|
|
112
|
+
- key: net.sock.host.addr
|
|
113
|
+
action: delete
|
|
114
|
+
- key: net.sock.host.port
|
|
115
|
+
action: delete
|
|
116
|
+
- key: user_agent.original
|
|
117
|
+
action: delete
|
|
118
|
+
resource/application:
|
|
119
|
+
attributes:
|
|
120
|
+
- key: cloud.provider
|
|
121
|
+
action: delete
|
|
122
|
+
- key: host.arch
|
|
123
|
+
action: delete
|
|
124
|
+
- key: aws.ecs.container.image.id
|
|
125
|
+
action: delete
|
|
126
|
+
- key: aws.ecs.task.arn
|
|
127
|
+
action: delete
|
|
128
|
+
- key: aws.log.stream.names
|
|
129
|
+
action: delete
|
|
130
|
+
- key: aws.log.stream.arns
|
|
131
|
+
action: delete
|
|
132
|
+
- key: cloud.platform
|
|
133
|
+
action: delete
|
|
134
|
+
- key: container.name
|
|
135
|
+
action: delete
|
|
136
|
+
- key: process.executable.path
|
|
137
|
+
action: delete
|
|
138
|
+
- key: process.runtime.version
|
|
139
|
+
action: delete
|
|
140
|
+
- key: telemetry.auto.version
|
|
141
|
+
action: delete
|
|
142
|
+
- key: telemetry.sdk.name
|
|
143
|
+
action: delete
|
|
144
|
+
- key: container.id
|
|
145
|
+
action: delete
|
|
146
|
+
- key: container.image.tag
|
|
147
|
+
action: delete
|
|
148
|
+
- key: process.runtime.name
|
|
149
|
+
action: delete
|
|
150
|
+
- key: service.namespace
|
|
151
|
+
action: delete
|
|
152
|
+
- key: telemetry.sdk.version
|
|
153
|
+
action: delete
|
|
154
|
+
- key: aws.ecs.task.family
|
|
155
|
+
action: delete
|
|
156
|
+
- key: aws.ecs.task.revision
|
|
157
|
+
action: delete
|
|
158
|
+
- key: aws.log.group.arns
|
|
159
|
+
action: delete
|
|
160
|
+
- key: container.image.name
|
|
161
|
+
action: delete
|
|
162
|
+
- key: os.description
|
|
163
|
+
action: delete
|
|
164
|
+
- key: os.type
|
|
165
|
+
action: delete
|
|
166
|
+
- key: process.runtime.description
|
|
167
|
+
action: delete
|
|
168
|
+
- key: version
|
|
169
|
+
action: delete
|
|
170
|
+
- key: aws.ecs.launchtype
|
|
171
|
+
action: delete
|
|
172
|
+
- key: aws.log.group.names
|
|
173
|
+
action: delete
|
|
174
|
+
- key: host.name
|
|
175
|
+
action: delete
|
|
176
|
+
- key: process.pid
|
|
177
|
+
action: delete
|
|
178
|
+
- key: telemetry.sdk.language
|
|
179
|
+
action: delete
|
|
180
|
+
- key: aws.ecs.container.arn
|
|
181
|
+
action: delete
|
|
182
|
+
- key: service.version
|
|
183
|
+
action: delete
|
|
184
|
+
- key: process.command_args
|
|
185
|
+
action: delete
|
|
186
|
+
- key: service
|
|
187
|
+
action: delete
|
|
188
|
+
## END OF LIFLIG CHANGES
|
|
189
|
+
resource:
|
|
190
|
+
attributes:
|
|
191
|
+
- key: ClusterName
|
|
192
|
+
from_attribute: aws.ecs.cluster.name
|
|
193
|
+
action: insert
|
|
194
|
+
- key: aws.ecs.cluster.name
|
|
195
|
+
action: delete
|
|
196
|
+
- key: ServiceName
|
|
197
|
+
from_attribute: aws.ecs.service.name
|
|
198
|
+
action: insert
|
|
199
|
+
- key: aws.ecs.service.name
|
|
200
|
+
action: delete
|
|
201
|
+
## THIS IS WHAT LIFLIG ADDED (bunch of sporadic removals)
|
|
202
|
+
- key: aws.ecs.task.id
|
|
203
|
+
action: delete
|
|
204
|
+
- key: TaskDefinitionFamily
|
|
205
|
+
from_attribute: aws.ecs.task.family
|
|
206
|
+
action: insert
|
|
207
|
+
- key: aws.ecs.task.family
|
|
208
|
+
action: delete
|
|
209
|
+
- key: aws.ecs.task.arn
|
|
210
|
+
action: delete
|
|
211
|
+
- key: aws.ecs.docker.name
|
|
212
|
+
action: delete
|
|
213
|
+
- key: aws.ecs.task.version
|
|
214
|
+
action: delete
|
|
215
|
+
- key: aws.ecs.task.pull_started_at
|
|
216
|
+
action: delete
|
|
217
|
+
- key: aws.ecs.task.pull_stopped_at
|
|
218
|
+
action: delete
|
|
219
|
+
- key: AvailabilityZone
|
|
220
|
+
from_attribute: cloud.zone
|
|
221
|
+
action: insert
|
|
222
|
+
- key: cloud.zone
|
|
223
|
+
action: delete
|
|
224
|
+
- key: aws.ecs.task.launch_type
|
|
225
|
+
action: delete
|
|
226
|
+
- key: Region
|
|
227
|
+
from_attribute: cloud.region
|
|
228
|
+
action: insert
|
|
229
|
+
- key: cloud.region
|
|
230
|
+
action: delete
|
|
231
|
+
- key: AccountId
|
|
232
|
+
from_attribute: cloud.account.id
|
|
233
|
+
action: insert
|
|
234
|
+
- key: cloud.account.id
|
|
235
|
+
action: delete
|
|
236
|
+
- key: container.id
|
|
237
|
+
action: delete
|
|
238
|
+
- key: container.name
|
|
239
|
+
action: delete
|
|
240
|
+
- key: container.image.name
|
|
241
|
+
action: delete
|
|
242
|
+
- key: aws.ecs.container.image.id
|
|
243
|
+
action: delete
|
|
244
|
+
- key: aws.ecs.container.exit_code
|
|
245
|
+
action: delete
|
|
246
|
+
- key: aws.ecs.container.created_at
|
|
247
|
+
action: delete
|
|
248
|
+
- key: aws.ecs.container.started_at
|
|
249
|
+
action: delete
|
|
250
|
+
- key: aws.ecs.container.finished_at
|
|
251
|
+
action: delete
|
|
252
|
+
- key: container.image.tag
|
|
253
|
+
action: delete
|
|
254
|
+
## END OF LIFLIG CHANGES
|
|
255
|
+
|
|
256
|
+
exporters:
|
|
257
|
+
awsxray:
|
|
258
|
+
## THIS IS WHAT LIFLIG ADDED
|
|
259
|
+
indexed_attributes: ["otel.resource.service.name"] # Max 50 attributes
|
|
260
|
+
## END OF LIFLIG CHANGES
|
|
261
|
+
awsemf/application:
|
|
262
|
+
namespace: ECS/AWSOTel/Application
|
|
263
|
+
log_group_name: '/aws/ecs/application/metrics'
|
|
264
|
+
## THIS IS WHAT LIFLIG ADDED
|
|
265
|
+
## Config docs at https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/exporter/awsemfexporter/README.md
|
|
266
|
+
## log retention is days to keep the emf metric logs.
|
|
267
|
+
log_retention: 365
|
|
268
|
+
resource_to_telemetry_conversion:
|
|
269
|
+
enabled: true
|
|
270
|
+
dimension_rollup_option: NoDimensionRollup
|
|
271
|
+
## No rollup means we keep all the dimensions on the metric, instead of merging similar metrics to one in CloudWatch
|
|
272
|
+
## END OF LIFLIG CHANGES
|
|
273
|
+
awsemf/performance:
|
|
274
|
+
namespace: ECS/ContainerInsights
|
|
275
|
+
log_group_name: '/aws/ecs/containerinsights/{ClusterName}/performance'
|
|
276
|
+
log_stream_name: '{TaskId}'
|
|
277
|
+
resource_to_telemetry_conversion:
|
|
278
|
+
enabled: true
|
|
279
|
+
dimension_rollup_option: NoDimensionRollup
|
|
280
|
+
metric_declarations:
|
|
281
|
+
- dimensions: [ [ ClusterName ], [ ClusterName, TaskDefinitionFamily ] ]
|
|
282
|
+
metric_name_selectors:
|
|
283
|
+
- MemoryUtilized
|
|
284
|
+
- MemoryReserved
|
|
285
|
+
- CpuUtilized
|
|
286
|
+
- CpuReserved
|
|
287
|
+
- NetworkRxBytes
|
|
288
|
+
- NetworkTxBytes
|
|
289
|
+
- StorageReadBytes
|
|
290
|
+
- StorageWriteBytes
|
|
291
|
+
- metric_name_selectors: [container.*]
|
|
292
|
+
|
|
293
|
+
service:
|
|
294
|
+
pipelines:
|
|
295
|
+
traces:
|
|
296
|
+
receivers: [otlp,awsxray]
|
|
297
|
+
## THIS IS WHAT LIFLIG ADDED
|
|
298
|
+
processors: [filter/traces, batch/traces]
|
|
299
|
+
exporters: [awsxray]
|
|
300
|
+
metrics/application:
|
|
301
|
+
receivers: [otlp]
|
|
302
|
+
processors: [filter/application, resource/application, attributes/application, batch/metrics]
|
|
303
|
+
exporters: [awsemf/application]
|
|
304
|
+
## END OF LIFLIG CHANGES
|
|
305
|
+
metrics/performance:
|
|
306
|
+
receivers: [awsecscontainermetrics ]
|
|
307
|
+
processors: [filter, metricstransform, resource]
|
|
308
|
+
exporters: [ awsemf/performance ]
|
|
309
|
+
|
|
310
|
+
extensions: [health_check]
|
package/lib/ecs/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { Cluster } from "./cluster";
|
|
2
2
|
export { FargateService } from "./fargate-service";
|
|
3
3
|
export { ListenerRule } from "./listener-rule";
|
|
4
|
+
export { OpenTelemetryCollectors } from "./open-telemetry";
|
|
4
5
|
export type { ClusterProps } from "./cluster";
|
|
5
6
|
export type { FargateServiceProps } from "./fargate-service";
|
|
6
7
|
export type { ListenerRuleProps } from "./listener-rule";
|
|
8
|
+
export type { OpenTelemetryCollectorsProps } from "./open-telemetry";
|
package/lib/ecs/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { Cluster } from "./cluster";
|
|
2
2
|
export { FargateService } from "./fargate-service";
|
|
3
3
|
export { ListenerRule } from "./listener-rule";
|
|
4
|
-
|
|
4
|
+
export { OpenTelemetryCollectors } from "./open-telemetry";
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZWNzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDbkMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQ2xELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUM5QyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB7IENsdXN0ZXIgfSBmcm9tIFwiLi9jbHVzdGVyXCJcbmV4cG9ydCB7IEZhcmdhdGVTZXJ2aWNlIH0gZnJvbSBcIi4vZmFyZ2F0ZS1zZXJ2aWNlXCJcbmV4cG9ydCB7IExpc3RlbmVyUnVsZSB9IGZyb20gXCIuL2xpc3RlbmVyLXJ1bGVcIlxuZXhwb3J0IHsgT3BlblRlbGVtZXRyeUNvbGxlY3RvcnMgfSBmcm9tIFwiLi9vcGVuLXRlbGVtZXRyeVwiXG5leHBvcnQgdHlwZSB7IENsdXN0ZXJQcm9wcyB9IGZyb20gXCIuL2NsdXN0ZXJcIlxuZXhwb3J0IHR5cGUgeyBGYXJnYXRlU2VydmljZVByb3BzIH0gZnJvbSBcIi4vZmFyZ2F0ZS1zZXJ2aWNlXCJcbmV4cG9ydCB0eXBlIHsgTGlzdGVuZXJSdWxlUHJvcHMgfSBmcm9tIFwiLi9saXN0ZW5lci1ydWxlXCJcbmV4cG9ydCB0eXBlIHsgT3BlblRlbGVtZXRyeUNvbGxlY3RvcnNQcm9wcyB9IGZyb20gXCIuL29wZW4tdGVsZW1ldHJ5XCJcbiJdfQ==
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as constructs from "constructs";
|
|
2
|
+
import * as ecs from "aws-cdk-lib/aws-ecs";
|
|
3
|
+
import { RetentionDays } from "aws-cdk-lib/aws-logs";
|
|
4
|
+
import { FargateService } from "./fargate-service";
|
|
5
|
+
export interface OpenTelemetryCollectorsProps {
|
|
6
|
+
service: FargateService;
|
|
7
|
+
/** @default 6 months **/
|
|
8
|
+
logRetention?: RetentionDays;
|
|
9
|
+
/** @default "amazon/aws-otel-collector:v0.43.1" */
|
|
10
|
+
dockerImage?: string;
|
|
11
|
+
/** Should be kept as `undefined` unless you know what you are doing.
|
|
12
|
+
* This is the YAML config for the OpenTelemetry collector sidecar.
|
|
13
|
+
*
|
|
14
|
+
* An example of a config can be found at https://github.com/aws-observability/aws-otel-collector/blob/0ae198c7e7b8c43bcc8715f54e52c879c04407b6/config/ecs/container-insights/otel-task-metrics-config.yaml
|
|
15
|
+
*
|
|
16
|
+
* @default a file in `assets` tuned to work for aws and strips known high-cardinality metrics (like those containing IP addresses and ports)
|
|
17
|
+
*/
|
|
18
|
+
awsOtelConfig?: string;
|
|
19
|
+
/** Overrides for the sidecar container.
|
|
20
|
+
* You do not need to specify this.
|
|
21
|
+
*
|
|
22
|
+
* Defaults:
|
|
23
|
+
* - cpu: 32 units
|
|
24
|
+
* - memory reservation: 24 MiB
|
|
25
|
+
* - memory limit: 256 MiB
|
|
26
|
+
*/
|
|
27
|
+
containerProps?: SidecarContainerProps;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Methods to enable collection of Open Telemetry (otel) data of a {@link FargateService}
|
|
31
|
+
* using a docker container with an otel agent.
|
|
32
|
+
*
|
|
33
|
+
*
|
|
34
|
+
* An example of a Java auto-instrumentation agent in Docker can be found
|
|
35
|
+
* [in liflig-rest-baseline Dockerfile](https://github.com/capralifecycle/liflig-rest-service-baseline/blob/a29b5a472c982aa7ce04d09d0e7cfdc92a6cc977/docker/Dockerfile#L9-L29).
|
|
36
|
+
*
|
|
37
|
+
* The agent must be configured to output metrics to a collector.
|
|
38
|
+
* That collector is what this construct provides.
|
|
39
|
+
* Usually, the agent is specified in the Dockerfile or as a dependency/library,
|
|
40
|
+
* and configured in the Dockerfile or in the application source code.
|
|
41
|
+
*
|
|
42
|
+
* Use this construct on a {@link FargateService} by constructing a new instance of {@link OpenTelemetryCollectors}
|
|
43
|
+
* and calling the {@link addOpenTelemetryCollectorSidecar} method on it.
|
|
44
|
+
*
|
|
45
|
+
* ```ts
|
|
46
|
+
* const service = FargateService(...);
|
|
47
|
+
*
|
|
48
|
+
* new OpenTelemetryCollectors(this, "OtelSidecar").addOpenTelemetryCollectorSidecar(service)
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* The sidecar exposes these ports to your service:
|
|
52
|
+
* - udp 2000 : AWS XRay
|
|
53
|
+
* - tcp 4317 : OpenTelemetry collection GRPC
|
|
54
|
+
* - tcp 4318 : OpenTelemetry collection HTTP
|
|
55
|
+
*
|
|
56
|
+
* ---
|
|
57
|
+
*
|
|
58
|
+
* You can also disable the OpenTelemetry instrumentation agent
|
|
59
|
+
* for Java-based services,
|
|
60
|
+
* by setting the appropriate environment variable with {@link disableOpenTelemetryJavaAgent}:
|
|
61
|
+
* ```ts
|
|
62
|
+
* const service = FargateService(...);
|
|
63
|
+
*
|
|
64
|
+
* OpenTelemetryCollectors.disableOpenTelemetryJavaAgent(service)
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* @see OpenTelemetryCollectors.addOpenTelemetryCollectorSidecar
|
|
68
|
+
*/
|
|
69
|
+
export declare class OpenTelemetryCollectors extends constructs.Construct {
|
|
70
|
+
private readonly props;
|
|
71
|
+
constructor(scope: constructs.Construct, id: string, props: OpenTelemetryCollectorsProps);
|
|
72
|
+
/**
|
|
73
|
+
* The OpenTelemetry Java agent may run by default in the Docker image.
|
|
74
|
+
* This method will tell the agent to disable itself.
|
|
75
|
+
*
|
|
76
|
+
* You might want to do this to avoid overhead or error logs from failed
|
|
77
|
+
* connection attempts to the otel collector.
|
|
78
|
+
*/
|
|
79
|
+
disableOpenTelemetryJavaAgent(): void;
|
|
80
|
+
/**
|
|
81
|
+
* The OpenTelemetry Java agent may run by default in the Docker image.
|
|
82
|
+
* This method will tell the agent to disable itself.
|
|
83
|
+
*
|
|
84
|
+
* You might want to do this to avoid overhead or error logs from failed
|
|
85
|
+
* connection attempts to the otel collector.
|
|
86
|
+
* @param service
|
|
87
|
+
*/
|
|
88
|
+
static disableOpenTelemetryJavaAgent(service: FargateService): void;
|
|
89
|
+
/**
|
|
90
|
+
* Adds a sidecar with an AWS Distro OpenTelemetry Collector.
|
|
91
|
+
* https://aws-otel.github.io/docs/setup/ecs
|
|
92
|
+
*
|
|
93
|
+
* You also need to add either the Java SDK for OTel or a Java agent,
|
|
94
|
+
* to capture telemetry and send to this collector.
|
|
95
|
+
*/
|
|
96
|
+
addOpenTelemetryCollectorSidecar(): void;
|
|
97
|
+
}
|
|
98
|
+
export type SidecarContainerProps = Pick<ecs.ContainerDefinitionProps, "cpu" | "memoryReservationMiB" | "memoryLimitMiB">;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import * as constructs from "constructs";
|
|
2
|
+
import * as ecs from "aws-cdk-lib/aws-ecs";
|
|
3
|
+
import * as iam from "aws-cdk-lib/aws-iam";
|
|
4
|
+
import * as logs from "aws-cdk-lib/aws-logs";
|
|
5
|
+
import { RetentionDays } from "aws-cdk-lib/aws-logs";
|
|
6
|
+
import { RemovalPolicy } from "aws-cdk-lib";
|
|
7
|
+
import { readFileSync } from "fs";
|
|
8
|
+
import { fileURLToPath } from "url";
|
|
9
|
+
import * as path from "path";
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = path.dirname(__filename);
|
|
12
|
+
/**
|
|
13
|
+
* Methods to enable collection of Open Telemetry (otel) data of a {@link FargateService}
|
|
14
|
+
* using a docker container with an otel agent.
|
|
15
|
+
*
|
|
16
|
+
*
|
|
17
|
+
* An example of a Java auto-instrumentation agent in Docker can be found
|
|
18
|
+
* [in liflig-rest-baseline Dockerfile](https://github.com/capralifecycle/liflig-rest-service-baseline/blob/a29b5a472c982aa7ce04d09d0e7cfdc92a6cc977/docker/Dockerfile#L9-L29).
|
|
19
|
+
*
|
|
20
|
+
* The agent must be configured to output metrics to a collector.
|
|
21
|
+
* That collector is what this construct provides.
|
|
22
|
+
* Usually, the agent is specified in the Dockerfile or as a dependency/library,
|
|
23
|
+
* and configured in the Dockerfile or in the application source code.
|
|
24
|
+
*
|
|
25
|
+
* Use this construct on a {@link FargateService} by constructing a new instance of {@link OpenTelemetryCollectors}
|
|
26
|
+
* and calling the {@link addOpenTelemetryCollectorSidecar} method on it.
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* const service = FargateService(...);
|
|
30
|
+
*
|
|
31
|
+
* new OpenTelemetryCollectors(this, "OtelSidecar").addOpenTelemetryCollectorSidecar(service)
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* The sidecar exposes these ports to your service:
|
|
35
|
+
* - udp 2000 : AWS XRay
|
|
36
|
+
* - tcp 4317 : OpenTelemetry collection GRPC
|
|
37
|
+
* - tcp 4318 : OpenTelemetry collection HTTP
|
|
38
|
+
*
|
|
39
|
+
* ---
|
|
40
|
+
*
|
|
41
|
+
* You can also disable the OpenTelemetry instrumentation agent
|
|
42
|
+
* for Java-based services,
|
|
43
|
+
* by setting the appropriate environment variable with {@link disableOpenTelemetryJavaAgent}:
|
|
44
|
+
* ```ts
|
|
45
|
+
* const service = FargateService(...);
|
|
46
|
+
*
|
|
47
|
+
* OpenTelemetryCollectors.disableOpenTelemetryJavaAgent(service)
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @see OpenTelemetryCollectors.addOpenTelemetryCollectorSidecar
|
|
51
|
+
*/
|
|
52
|
+
export class OpenTelemetryCollectors extends constructs.Construct {
|
|
53
|
+
props;
|
|
54
|
+
constructor(scope, id, props) {
|
|
55
|
+
super(scope, id);
|
|
56
|
+
this.props = props;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The OpenTelemetry Java agent may run by default in the Docker image.
|
|
60
|
+
* This method will tell the agent to disable itself.
|
|
61
|
+
*
|
|
62
|
+
* You might want to do this to avoid overhead or error logs from failed
|
|
63
|
+
* connection attempts to the otel collector.
|
|
64
|
+
*/
|
|
65
|
+
disableOpenTelemetryJavaAgent() {
|
|
66
|
+
OpenTelemetryCollectors.disableOpenTelemetryJavaAgent(this.props.service);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The OpenTelemetry Java agent may run by default in the Docker image.
|
|
70
|
+
* This method will tell the agent to disable itself.
|
|
71
|
+
*
|
|
72
|
+
* You might want to do this to avoid overhead or error logs from failed
|
|
73
|
+
* connection attempts to the otel collector.
|
|
74
|
+
* @param service
|
|
75
|
+
*/
|
|
76
|
+
static disableOpenTelemetryJavaAgent(service) {
|
|
77
|
+
service.taskDefinition.defaultContainer?.addEnvironment("OTEL_JAVAAGENT_ENABLED", "false");
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Adds a sidecar with an AWS Distro OpenTelemetry Collector.
|
|
81
|
+
* https://aws-otel.github.io/docs/setup/ecs
|
|
82
|
+
*
|
|
83
|
+
* You also need to add either the Java SDK for OTel or a Java agent,
|
|
84
|
+
* to capture telemetry and send to this collector.
|
|
85
|
+
*/
|
|
86
|
+
addOpenTelemetryCollectorSidecar() {
|
|
87
|
+
new OpenTelemetryPolicies(this, "OpenTelemetryPolicies", {
|
|
88
|
+
taskDefinition: this.props.service.taskDefinition,
|
|
89
|
+
});
|
|
90
|
+
this.props.service.taskDefinition.addExtension(new OpenTelemetryCollectorSidecar(this, this.props.logRetention, this.props.dockerImage, this.props.awsOtelConfig, this.props.containerProps));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Adds a sidecar with an AWS Distro OpenTelemetry Collector.
|
|
95
|
+
* https://aws-otel.github.io/docs/setup/ecs
|
|
96
|
+
*
|
|
97
|
+
* You also need to add either the Java SDK for OTel or a Java agent,
|
|
98
|
+
* to capture telemetry and send to this collector.
|
|
99
|
+
*/
|
|
100
|
+
class OpenTelemetryCollectorSidecar {
|
|
101
|
+
construct;
|
|
102
|
+
logRetention;
|
|
103
|
+
dockerImage;
|
|
104
|
+
awsOtelConfig;
|
|
105
|
+
containerProps;
|
|
106
|
+
constructor(construct, logRetention, dockerImage, awsOtelConfig, containerProps) {
|
|
107
|
+
this.construct = construct;
|
|
108
|
+
this.logRetention = logRetention;
|
|
109
|
+
this.dockerImage = dockerImage;
|
|
110
|
+
this.awsOtelConfig = awsOtelConfig;
|
|
111
|
+
this.containerProps = containerProps;
|
|
112
|
+
}
|
|
113
|
+
extend(taskDefinition) {
|
|
114
|
+
if (taskDefinition.networkMode !== ecs.NetworkMode.AWS_VPC) {
|
|
115
|
+
throw new Error("Task NetworkMode must be AWS_VPC: " + taskDefinition.networkMode);
|
|
116
|
+
}
|
|
117
|
+
const commands = {
|
|
118
|
+
metricsAndTraces: "--config=/etc/ecs/ecs-default-config.yaml",
|
|
119
|
+
metricsAndTracesAndContainerResources: "--config=/etc/ecs/container-insights/otel-task-metrics-config.yaml",
|
|
120
|
+
};
|
|
121
|
+
const logGroup = new logs.LogGroup(this.construct, "CollectorLogGroup", {
|
|
122
|
+
retention: this.logRetention ?? RetentionDays.SIX_MONTHS,
|
|
123
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
124
|
+
});
|
|
125
|
+
const sidecarImage = this.dockerImage ?? "amazon/aws-otel-collector:v0.43.1";
|
|
126
|
+
const sidecar = taskDefinition.addContainer("aws-opentelemetry-collector", {
|
|
127
|
+
cpu: this.containerProps?.cpu ?? 32,
|
|
128
|
+
memoryReservationMiB: this.containerProps?.memoryReservationMiB ?? 24,
|
|
129
|
+
memoryLimitMiB: this.containerProps?.memoryLimitMiB ?? 256,
|
|
130
|
+
image: ecs.ContainerImage.fromRegistry(sidecarImage),
|
|
131
|
+
command: [commands.metricsAndTracesAndContainerResources], // This is not used when the AOT_CONFIG_CONTENT is set!
|
|
132
|
+
environment: {
|
|
133
|
+
// You can alternatively create an SSM parameter with the config, and pass it to the `secrets` option
|
|
134
|
+
AOT_CONFIG_CONTENT: this.awsOtelConfig ?? awsOtelCustomConfigYaml,
|
|
135
|
+
},
|
|
136
|
+
logging: ecs.LogDrivers.awsLogs({
|
|
137
|
+
logGroup: logGroup,
|
|
138
|
+
streamPrefix: "ecs",
|
|
139
|
+
}),
|
|
140
|
+
});
|
|
141
|
+
// A dependency should be added to all containers that export metrics.
|
|
142
|
+
// We are currently assuming that this is only the default container
|
|
143
|
+
taskDefinition.defaultContainer?.addContainerDependencies({
|
|
144
|
+
container: sidecar,
|
|
145
|
+
condition: ecs.ContainerDependencyCondition.START,
|
|
146
|
+
});
|
|
147
|
+
/*
|
|
148
|
+
* aws-otel-collector exposes these ports, and more:
|
|
149
|
+
* - udp 2000 : AWS XRay
|
|
150
|
+
* - tcp 4317 : OpenTelemetry collection GRPC
|
|
151
|
+
* - tcp 4318 : OpenTelemetry collection HTTP
|
|
152
|
+
*
|
|
153
|
+
* These are defined in the yaml config for the collector.
|
|
154
|
+
*/
|
|
155
|
+
taskDefinition.defaultContainer?.addEnvironment("AWS_XRAY_DAEMON_ADDRESS", "http://localhost:2000");
|
|
156
|
+
taskDefinition.defaultContainer?.addEnvironment("OTEL_EXPORTER_OTLP_ENDPOINT", "http://localhost:4317");
|
|
157
|
+
taskDefinition.defaultContainer?.addEnvironment("OTEL_JAVAAGENT_ENABLED", "true");
|
|
158
|
+
if (!taskDefinition.isFargateCompatible) {
|
|
159
|
+
// This extension is made for the FargateService, so this is a requirement.
|
|
160
|
+
throw new Error("This task definition can not be ran on fargate! " +
|
|
161
|
+
taskDefinition.node.id);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Grants the sidecar permissions to create logs, metrics and XRay traces by extending the task roles.
|
|
167
|
+
*/
|
|
168
|
+
class OpenTelemetryPolicies extends constructs.Construct {
|
|
169
|
+
constructor(scope, id, props) {
|
|
170
|
+
super(scope, id);
|
|
171
|
+
const awsDistroOpenTelemetryPolicyStatement = new iam.PolicyStatement({
|
|
172
|
+
effect: iam.Effect.ALLOW,
|
|
173
|
+
resources: ["*"],
|
|
174
|
+
actions: [
|
|
175
|
+
"logs:PutLogEvents",
|
|
176
|
+
"logs:CreateLogGroup",
|
|
177
|
+
"logs:CreateLogStream",
|
|
178
|
+
"logs:DescribeLogStreams",
|
|
179
|
+
"logs:DescribeLogGroups",
|
|
180
|
+
"logs:PutRetentionPolicy",
|
|
181
|
+
"xray:PutTraceSegments",
|
|
182
|
+
"xray:PutTelemetryRecords",
|
|
183
|
+
"xray:GetSamplingRules",
|
|
184
|
+
"xray:GetSamplingTargets",
|
|
185
|
+
"xray:GetSamplingStatisticSummaries",
|
|
186
|
+
"cloudwatch:PutMetricData",
|
|
187
|
+
"ec2:DescribeVolumes",
|
|
188
|
+
"ec2:DescribeTags",
|
|
189
|
+
"ssm:GetParameters",
|
|
190
|
+
],
|
|
191
|
+
});
|
|
192
|
+
props.taskDefinition.addToTaskRolePolicy(awsDistroOpenTelemetryPolicyStatement);
|
|
193
|
+
props.taskDefinition.addToExecutionRolePolicy(awsDistroOpenTelemetryPolicyStatement);
|
|
194
|
+
props.taskDefinition.executionRole?.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName("CloudWatchLogsFullAccess"));
|
|
195
|
+
props.taskDefinition.executionRole?.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMReadOnlyAccess"));
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* This is a modified version of `./etc/ecs/container-insights/otel-task-metrics-config.yaml`
|
|
200
|
+
* where we add `resource_to_telemetry_conversion` so the otel resource `service.name`
|
|
201
|
+
* can be added to the metric. This is useful because you can filter in metrics based on service,
|
|
202
|
+
* instead of grouping e.g. all services' memory usage under the same metric.
|
|
203
|
+
*
|
|
204
|
+
* @see https://aws-otel.github.io/docs/setup/ecs/config-through-ssm
|
|
205
|
+
* @see https://aws-otel.github.io/docs/getting-started/cloudwatch-metrics#cloudwatch-emf-exporter-awsemf
|
|
206
|
+
*/
|
|
207
|
+
const awsOtelCustomConfigYaml = readFileSync(path.resolve(__dirname, "..", "..", "assets", "open-telemetry", "otel-collector-task-metrics-config.yaml"), "utf-8")
|
|
208
|
+
.split("\n")
|
|
209
|
+
.filter((line) => !/^\s*##/.test(line)) // Skip comments starting with ##
|
|
210
|
+
.join("\n");
|
|
211
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3Blbi10ZWxlbWV0cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZWNzL29wZW4tdGVsZW1ldHJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxVQUFVLE1BQU0sWUFBWSxDQUFBO0FBQ3hDLE9BQU8sS0FBSyxHQUFHLE1BQU0scUJBQXFCLENBQUE7QUFDMUMsT0FBTyxLQUFLLEdBQUcsTUFBTSxxQkFBcUIsQ0FBQTtBQUMxQyxPQUFPLEtBQUssSUFBSSxNQUFNLHNCQUFzQixDQUFBO0FBQzVDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBRTNDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxJQUFJLENBQUE7QUFDakMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLEtBQUssQ0FBQTtBQUNuQyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUU1QixNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtBQUNqRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFBO0FBK0IxQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBdUNHO0FBQ0gsTUFBTSxPQUFPLHVCQUF3QixTQUFRLFVBQVUsQ0FBQyxTQUFTO0lBSTVDO0lBSG5CLFlBQ0UsS0FBMkIsRUFDM0IsRUFBVSxFQUNPLEtBQW1DO1FBRXBELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFGQyxVQUFLLEdBQUwsS0FBSyxDQUE4QjtJQUd0RCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksNkJBQTZCO1FBQ2xDLHVCQUF1QixDQUFDLDZCQUE2QixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFD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QkFBeUI7Z0JBQ3pCLG9DQUFvQztnQkFDcEMsMEJBQTBCO2dCQUMxQixxQkFBcUI7Z0JBQ3JCLGtCQUFrQjtnQkFDbEIsbUJBQW1CO2FBQ3BCO1NBQ0YsQ0FBQyxDQUFBO1FBRUYsS0FBSyxDQUFDLGNBQWMsQ0FBQyxtQkFBbUIsQ0FDdEMscUNBQXFDLENBQ3RDLENBQUE7UUFFRCxLQUFLLENBQUMsY0FBYyxDQUFDLHdCQUF3QixDQUMzQyxxQ0FBcUMsQ0FDdEMsQ0FBQTtRQUNELEtBQUssQ0FBQyxjQUFjLENBQUMsYUFBYSxFQUFFLGdCQUFnQixDQUNsRCxHQUFHLENBQUMsYUFBYSxDQUFDLHdCQUF3QixDQUFDLDBCQUEwQixDQUFDLENBQ3ZFLENBQUE7UUFDRCxLQUFLLENBQUMsY0FBYyxDQUFDLGFBQWEsRUFBRSxnQkFBZ0IsQ0FDbEQsR0FBRyxDQUFDLGFBQWEsQ0FBQyx3QkFBd0IsQ0FBQyx5QkFBeUIsQ0FBQyxDQUN0RSxDQUFBO0lBQ0gsQ0FBQztDQUNGO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLHVCQUF1QixHQUFHLFlBQVksQ0FDMUMsSUFBSSxDQUFDLE9BQU8sQ0FDVixTQUFTLEVBQ1QsSUFBSSxFQUNKLElBQUksRUFDSixRQUFRLEVBQ1IsZ0JBQWdCLEVBQ2hCLHlDQUF5QyxDQUMxQyxFQUNELE9BQU8sQ0FDUjtLQUNFLEtBQUssQ0FBQyxJQUFJLENBQUM7S0FDWCxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLGlDQUFpQztLQUN4RSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjb25zdHJ1Y3RzIGZyb20gXCJjb25zdHJ1Y3RzXCJcbmltcG9ydCAqIGFzIGVjcyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVjc1wiXG5pbXBvcnQgKiBhcyBpYW0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIlxuaW1wb3J0ICogYXMgbG9ncyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxvZ3NcIlxuaW1wb3J0IHsgUmV0ZW50aW9uRGF5cyB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbG9nc1wiXG5pbXBvcnQgeyBSZW1vdmFsUG9saWN5IH0gZnJvbSBcImF3cy1jZGstbGliXCJcbmltcG9ydCB7IEZhcmdhdGVTZXJ2aWNlIH0gZnJvbSBcIi4vZmFyZ2F0ZS1zZXJ2aWNlXCJcbmltcG9ydCB7IHJlYWRGaWxlU3luYyB9IGZyb20gXCJmc1wiXG5pbXBvcnQgeyBmaWxlVVJMVG9QYXRoIH0gZnJvbSBcInVybFwiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCJcblxuY29uc3QgX19maWxlbmFtZSA9IGZpbGVVUkxUb1BhdGgoaW1wb3J0Lm1ldGEudXJsKVxuY29uc3QgX19kaXJuYW1lID0gcGF0aC5kaXJuYW1lKF9fZmlsZW5hbWUpXG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlblRlbGVtZXRyeUNvbGxlY3RvcnNQcm9wcyB7XG4gIHNlcnZpY2U6IEZhcmdhdGVTZXJ2aWNlXG5cbiAgLyoqIEBkZWZhdWx0IDYgbW9udGhzICoqL1xuICBsb2dSZXRlbnRpb24/OiBSZXRlbnRpb25EYXlzXG5cbiAgLyoqIEBkZWZhdWx0IFwiYW1hem9uL2F3cy1vdGVsLWNvbGxlY3Rvcjp2MC40My4xXCIgKi9cbiAgZG9ja2VySW1hZ2U/OiBzdHJpbmdcblxuICAvKiogU2hvdWxkIGJlIGtlcHQgYXMgYHVuZGVmaW5lZGAgdW5sZXNzIHlvdSBrbm93IHdoYXQgeW91IGFyZSBkb2luZy5cbiAgICogVGhpcyBpcyB0aGUgWUFNTCBjb25maWcgZm9yIHRoZSBPcGVuVGVsZW1ldHJ5IGNvbGxlY3RvciBzaWRlY2FyLlxuICAgKlxuICAgKiBBbiBleGFtcGxlIG9mIGEgY29uZmlnIGNhbiBiZSBmb3VuZCBhdCBodHRwczovL2dpdGh1Yi5jb20vYXdzLW9ic2VydmFiaWxpdHkvYXdzLW90ZWwtY29sbGVjdG9yL2Jsb2IvMGFlMTk4YzdlN2I4YzQzYmNjODcxNWY1NGU1MmM4NzljMDQ0MDdiNi9jb25maWcvZWNzL2NvbnRhaW5lci1pbnNpZ2h0cy9vdGVsLXRhc2stbWV0cmljcy1jb25maWcueWFtbFxuICAgKlxuICAgKiBAZGVmYXVsdCBhIGZpbGUgaW4gYGFzc2V0c2AgdHVuZWQgdG8gd29yayBmb3IgYXdzIGFuZCBzdHJpcHMga25vd24gaGlnaC1jYXJkaW5hbGl0eSBtZXRyaWNzIChsaWtlIHRob3NlIGNvbnRhaW5pbmcgSVAgYWRkcmVzc2VzIGFuZCBwb3J0cylcbiAgICovXG4gIGF3c090ZWxDb25maWc/OiBzdHJpbmdcblxuICAvKiogT3ZlcnJpZGVzIGZvciB0aGUgc2lkZWNhciBjb250YWluZXIuXG4gICAqIFlvdSBkbyBub3QgbmVlZCB0byBzcGVjaWZ5IHRoaXMuXG4gICAqXG4gICAqIERlZmF1bHRzOlxuICAgKiAtIGNwdTogMzIgdW5pdHNcbiAgICogLSBtZW1vcnkgcmVzZXJ2YXRpb246IDI0IE1pQlxuICAgKiAtIG1lbW9yeSBsaW1pdDogMjU2IE1pQlxuICAgKi9cbiAgY29udGFpbmVyUHJvcHM/OiBTaWRlY2FyQ29udGFpbmVyUHJvcHNcbn1cblxuLyoqXG4gKiBNZXRob2RzIHRvIGVuYWJsZSBjb2xsZWN0aW9uIG9mIE9wZW4gVGVsZW1ldHJ5IChvdGVsKSBkYXRhIG9mIGEge0BsaW5rIEZhcmdhdGVTZXJ2aWNlfVxuICogdXNpbmcgYSBkb2NrZXIgY29udGFpbmVyIHdpdGggYW4gb3RlbCBhZ2VudC5cbiAqXG4gKlxuICogQW4gZXhhbXBsZSBvZiBhIEphdmEgYXV0by1pbnN0cnVtZW50YXRpb24gYWdlbnQgaW4gRG9ja2VyIGNhbiBiZSBmb3VuZFxuICogW2luIGxpZmxpZy1yZXN0LWJhc2VsaW5lIERvY2tlcmZpbGVdKGh0dHBzOi8vZ2l0aHViLmNvbS9jYXByYWxpZmVjeWNsZS9saWZsaWctcmVzdC1zZXJ2aWNlLWJhc2VsaW5lL2Jsb2IvYTI5YjVhNDcyYzk4MmFhN2NlMDRkMDlkMGU3Y2ZkYzkyYTZjYzk3Ny9kb2NrZXIvRG9ja2VyZmlsZSNMOS1MMjkpLlxuICpcbiAqIFRoZSBhZ2VudCBtdXN0IGJlIGNvbmZpZ3VyZWQgdG8gb3V0cHV0IG1ldHJpY3MgdG8gYSBjb2xsZWN0b3IuXG4gKiBUaGF0IGNvbGxlY3RvciBpcyB3aGF0IHRoaXMgY29uc3RydWN0IHByb3ZpZGVzLlxuICogVXN1YWxseSwgdGhlIGFnZW50IGlzIHNwZWNpZmllZCBpbiB0aGUgRG9ja2VyZmlsZSBvciBhcyBhIGRlcGVuZGVuY3kvbGlicmFyeSxcbiAqIGFuZCBjb25maWd1cmVkIGluIHRoZSBEb2NrZXJmaWxlIG9yIGluIHRoZSBhcHBsaWNhdGlvbiBzb3VyY2UgY29kZS5cbiAqXG4gKiBVc2UgdGhpcyBjb25zdHJ1Y3Qgb24gYSB7QGxpbmsgRmFyZ2F0ZVNlcnZpY2V9IGJ5IGNvbnN0cnVjdGluZyBhIG5ldyBpbnN0YW5jZSBvZiB7QGxpbmsgT3BlblRlbGVtZXRyeUNvbGxlY3RvcnN9XG4gKiBhbmQgY2FsbGluZyB0aGUge0BsaW5rIGFkZE9wZW5UZWxlbWV0cnlDb2xsZWN0b3JTaWRlY2FyfSBtZXRob2Qgb24gaXQuXG4gKlxuICogYGBgdHNcbiAqIGNvbnN0IHNlcnZpY2UgPSBGYXJnYXRlU2VydmljZSguLi4pO1xuICpcbiAqIG5ldyBPcGVuVGVsZW1ldHJ5Q29sbGVjdG9ycyh0aGlzLCBcIk90ZWxTaWRlY2FyXCIpLmFkZE9wZW5UZWxlbWV0cnlDb2xsZWN0b3JTaWRlY2FyKHNlcnZpY2UpXG4gKiBgYGBcbiAqXG4gKiBUaGUgc2lkZWNhciBleHBvc2VzIHRoZXNlIHBvcnRzIHRvIHlvdXIgc2VydmljZTpcbiAqIC0gdWRwIDIwMDAgOiBBV1MgWFJheVxuICogLSB0Y3AgNDMxNyA6IE9wZW5UZWxlbWV0cnkgY29sbGVjdGlvbiBHUlBDXG4gKiAtIHRjcCA0MzE4IDogT3BlblRlbGVtZXRyeSBjb2xsZWN0aW9uIEhUVFBcbiAqXG4gKiAtLS1cbiAqXG4gKiBZb3UgY2FuIGFsc28gZGlzYWJsZSB0aGUgT3BlblRlbGVtZXRyeSBpbnN0cnVtZW50YXRpb24gYWdlbnRcbiAqIGZvciBKYXZhLWJhc2VkIHNlcnZpY2VzLFxuICogYnkgc2V0dGluZyB0aGUgYXBwcm9wcmlhdGUgZW52aXJvbm1lbnQgdmFyaWFibGUgd2l0aCB7QGxpbmsgZGlzYWJsZU9wZW5UZWxlbWV0cnlKYXZhQWdlbnR9OlxuICogYGBgdHNcbiAqIGNvbnN0IHNlcnZpY2UgPSBGYXJnYXRlU2VydmljZSguLi4pO1xuICpcbiAqIE9wZW5UZWxlbWV0cnlDb2xsZWN0b3JzLmRpc2FibGVPcGVuVGVsZW1ldHJ5SmF2YUFnZW50KHNlcnZpY2UpXG4gKiBgYGBcbiAqXG4gKiBAc2VlIE9wZW5UZWxlbWV0cnlDb2xsZWN0b3JzLmFkZE9wZW5UZWxlbWV0cnlDb2xsZWN0b3JTaWRlY2FyXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuVGVsZW1ldHJ5Q29sbGVjdG9ycyBleHRlbmRzIGNvbnN0cnVjdHMuQ29uc3RydWN0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IGNvbnN0cnVjdHMuQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBwcm9wczogT3BlblRlbGVtZXRyeUNvbGxlY3RvcnNQcm9wcyxcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKVxuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBPcGVuVGVsZW1ldHJ5IEphdmEgYWdlbnQgbWF5IHJ1biBieSBkZWZhdWx0IGluIHRoZSBEb2NrZXIgaW1hZ2UuXG4gICAqIFRoaXMgbWV0aG9kIHdpbGwgdGVsbCB0aGUgYWdlbnQgdG8gZGlzYWJsZSBpdHNlbGYuXG4gICAqXG4gICAqIFlvdSBtaWdodCB3YW50IHRvIGRvIHRoaXMgdG8gYXZvaWQgb3ZlcmhlYWQgb3IgZXJyb3IgbG9ncyBmcm9tIGZhaWxlZFxuICAgKiBjb25uZWN0aW9uIGF0dGVtcHRzIHRvIHRoZSBvdGVsIGNvbGxlY3Rvci5cbiAgICovXG4gIHB1YmxpYyBkaXNhYmxlT3BlblRlbGVtZXRyeUphdmFBZ2VudCgpIHtcbiAgICBPcGVuVGVsZW1ldHJ5Q29sbGVjdG9ycy5kaXNhYmxlT3BlblRlbGVtZXRyeUphdmFBZ2VudCh0aGlzLnByb3BzLnNlcnZpY2UpXG4gIH1cblxuICAvKipcbiAgICogVGhlIE9wZW5UZWxlbWV0cnkgSmF2YSBhZ2VudCBtYXkgcnVuIGJ5IGRlZmF1bHQgaW4gdGhlIERvY2tlciBpbWFnZS5cbiAgICogVGhpcyBtZXRob2Qgd2lsbCB0ZWxsIHRoZSBhZ2VudCB0byBkaXNhYmxlIGl0c2VsZi5cbiAgICpcbiAgICogWW91IG1pZ2h0IHdhbnQgdG8gZG8gdGhpcyB0byBhdm9pZCBvdmVyaGVhZCBvciBlcnJvciBsb2dzIGZyb20gZmFpbGVkXG4gICAqIGNvbm5lY3Rpb24gYXR0ZW1wdHMgdG8gdGhlIG90ZWwgY29sbGVjdG9yLlxuICAgKiBAcGFyYW0gc2VydmljZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBkaXNhYmxlT3BlblRlbGVtZXRyeUphdmFBZ2VudChzZXJ2aWNlOiBGYXJnYXRlU2VydmljZSkge1xuICAgIHNlcnZpY2UudGFza0RlZmluaXRpb24uZGVmYXVsdENvbnRhaW5lcj8uYWRkRW52aXJvbm1lbnQoXG4gICAgICBcIk9URUxfSkFWQUFHRU5UX0VOQUJMRURcIixcbiAgICAgIFwiZmFsc2VcIixcbiAgICApXG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHNpZGVjYXIgd2l0aCBhbiBBV1MgRGlzdHJvIE9wZW5UZWxlbWV0cnkgQ29sbGVjdG9yLlxuICAgKiBodHRwczovL2F3cy1vdGVsLmdpdGh1Yi5pby9kb2NzL3NldHVwL2Vjc1xuICAgKlxuICAgKiBZb3UgYWxzbyBuZWVkIHRvIGFkZCBlaXRoZXIgdGhlIEphdmEgU0RLIGZvciBPVGVsIG9yIGEgSmF2YSBhZ2VudCxcbiAgICogdG8gY2FwdHVyZSB0ZWxlbWV0cnkgYW5kIHNlbmQgdG8gdGhpcyBjb2xsZWN0b3IuXG4gICAqL1xuICBwdWJsaWMgYWRkT3BlblRlbGVtZXRyeUNvbGxlY3RvclNpZGVjYXIoKSB7XG4gICAgbmV3IE9wZW5UZWxlbWV0cnlQb2xpY2llcyh0aGlzLCBcIk9wZW5UZWxlbWV0cnlQb2xpY2llc1wiLCB7XG4gICAgICB0YXNrRGVmaW5pdGlvbjogdGhpcy5wcm9wcy5zZXJ2aWNlLnRhc2tEZWZpbml0aW9uLFxuICAgIH0pXG5cbiAgICB0aGlzLnByb3BzLnNlcnZpY2UudGFza0RlZmluaXRpb24uYWRkRXh0ZW5zaW9uKFxuICAgICAgbmV3IE9wZW5UZWxlbWV0cnlDb2xsZWN0b3JTaWRlY2FyKFxuICAgICAgICB0aGlzLFxuICAgICAgICB0aGlzLnByb3BzLmxvZ1JldGVudGlvbixcbiAgICAgICAgdGhpcy5wcm9wcy5kb2NrZXJJbWFnZSxcbiAgICAgICAgdGhpcy5wcm9wcy5hd3NPdGVsQ29uZmlnLFxuICAgICAgICB0aGlzLnByb3BzLmNvbnRhaW5lclByb3BzLFxuICAgICAgKSxcbiAgICApXG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgU2lkZWNhckNvbnRhaW5lclByb3BzID0gUGljazxcbiAgZWNzLkNvbnRhaW5lckRlZmluaXRpb25Qcm9wcyxcbiAgXCJjcHVcIiB8IFwibWVtb3J5UmVzZXJ2YXRpb25NaUJcIiB8IFwibWVtb3J5TGltaXRNaUJcIlxuPlxuXG4vKipcbiAqIEFkZHMgYSBzaWRlY2FyIHdpdGggYW4gQVdTIERpc3RybyBPcGVuVGVsZW1ldHJ5IENvbGxlY3Rvci5cbiAqIGh0dHBzOi8vYXdzLW90ZWwuZ2l0aHViLmlvL2RvY3Mvc2V0dXAvZWNzXG4gKlxuICogWW91IGFsc28gbmVlZCB0byBhZGQgZWl0aGVyIHRoZSBKYXZhIFNESyBmb3IgT1RlbCBvciBhIEphdmEgYWdlbnQsXG4gKiB0byBjYXB0dXJlIHRlbGVtZXRyeSBhbmQgc2VuZCB0byB0aGlzIGNvbGxlY3Rvci5cbiAqL1xuY2xhc3MgT3BlblRlbGVtZXRyeUNvbGxlY3RvclNpZGVjYXIgaW1wbGVtZW50cyBlY3MuSVRhc2tEZWZpbml0aW9uRXh0ZW5zaW9uIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb25zdHJ1Y3Q6IGNvbnN0cnVjdHMuQ29uc3RydWN0LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbG9nUmV0ZW50aW9uPzogUmV0ZW50aW9uRGF5cyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGRvY2tlckltYWdlPzogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYXdzT3RlbENvbmZpZz86IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNvbnRhaW5lclByb3BzPzogU2lkZWNhckNvbnRhaW5lclByb3BzLFxuICApIHt9XG5cbiAgZXh0ZW5kKHRhc2tEZWZpbml0aW9uOiBlY3MuVGFza0RlZmluaXRpb24pOiB2b2lkIHtcbiAgICBpZiAodGFza0RlZmluaXRpb24ubmV0d29ya01vZGUgIT09IGVjcy5OZXR3b3JrTW9kZS5BV1NfVlBDKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiVGFzayBOZXR3b3JrTW9kZSBtdXN0IGJlIEFXU19WUEM6IFwiICsgdGFza0RlZmluaXRpb24ubmV0d29ya01vZGUsXG4gICAgICApXG4gICAgfVxuXG4gICAgY29uc3QgY29tbWFuZHMgPSB7XG4gICAgICBtZXRyaWNzQW5kVHJhY2VzOiBcIi0tY29uZmlnPS9ldGMvZWNzL2Vjcy1kZWZhdWx0LWNvbmZpZy55YW1sXCIsXG4gICAgICBtZXRyaWNzQW5kVHJhY2VzQW5kQ29udGFpbmVyUmVzb3VyY2VzOlxuICAgICAgICBcIi0tY29uZmlnPS9ldGMvZWNzL2NvbnRhaW5lci1pbnNpZ2h0cy9vdGVsLXRhc2stbWV0cmljcy1jb25maWcueWFtbFwiLFxuICAgIH1cblxuICAgIGNvbnN0IGxvZ0dyb3VwID0gbmV3IGxvZ3MuTG9nR3JvdXAodGhpcy5jb25zdHJ1Y3QsIFwiQ29sbGVjdG9yTG9nR3JvdXBcIiwge1xuICAgICAgcmV0ZW50aW9uOiB0aGlzLmxvZ1JldGVudGlvbiA/PyBSZXRlbnRpb25EYXlzLlNJWF9NT05USFMsXG4gICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAgfSlcblxuICAgIGNvbnN0IHNpZGVjYXJJbWFnZSA9IHRoaXMuZG9ja2VySW1hZ2UgPz8gXCJhbWF6b24vYXdzLW90ZWwtY29sbGVjdG9yOnYwLjQzLjFcIlxuICAgIGNvbnN0IHNpZGVjYXIgPSB0YXNrRGVmaW5pdGlvbi5hZGRDb250YWluZXIoXCJhd3Mtb3BlbnRlbGVtZXRyeS1jb2xsZWN0b3JcIiwge1xuICAgICAgY3B1OiB0aGlzLmNvbnRhaW5lclByb3BzPy5jcHUgPz8gMzIsXG4gICAgICBtZW1vcnlSZXNlcnZhdGlvbk1pQjogdGhpcy5jb250YWluZXJQcm9wcz8ubWVtb3J5UmVzZXJ2YXRpb25NaUIgPz8gMjQsXG4gICAgICBtZW1vcnlMaW1pdE1pQjogdGhpcy5jb250YWluZXJQcm9wcz8ubWVtb3J5TGltaXRNaUIgPz8gMjU2LFxuICAgICAgaW1hZ2U6IGVjcy5Db250YWluZXJJbWFnZS5mcm9tUmVnaXN0cnkoc2lkZWNhckltYWdlKSxcbiAgICAgIGNvbW1hbmQ6IFtjb21tYW5kcy5tZXRyaWNzQW5kVHJhY2VzQW5kQ29udGFpbmVyUmVzb3VyY2VzXSwgLy8gVGhpcyBpcyBub3QgdXNlZCB3aGVuIHRoZSBBT1RfQ09ORklHX0NPTlRFTlQgaXMgc2V0IVxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgLy8gWW91IGNhbiBhbHRlcm5hdGl2ZWx5IGNyZWF0ZSBhbiBTU00gcGFyYW1ldGVyIHdpdGggdGhlIGNvbmZpZywgYW5kIHBhc3MgaXQgdG8gdGhlIGBzZWNyZXRzYCBvcHRpb25cbiAgICAgICAgQU9UX0NPTkZJR19DT05URU5UOiB0aGlzLmF3c090ZWxDb25maWcgPz8gYXdzT3RlbEN1c3RvbUNvbmZpZ1lhbWwsXG4gICAgICB9LFxuICAgICAgbG9nZ2luZzogZWNzLkxvZ0RyaXZlcnMuYXdzTG9ncyh7XG4gICAgICAgIGxvZ0dyb3VwOiBsb2dHcm91cCxcbiAgICAgICAgc3RyZWFtUHJlZml4OiBcImVjc1wiLFxuICAgICAgfSksXG4gICAgfSlcblxuICAgIC8vIEEgZGVwZW5kZW5jeSBzaG91bGQgYmUgYWRkZWQgdG8gYWxsIGNvbnRhaW5lcnMgdGhhdCBleHBvcnQgbWV0cmljcy5cbiAgICAvLyBXZSBhcmUgY3VycmVudGx5IGFzc3VtaW5nIHRoYXQgdGhpcyBpcyBvbmx5IHRoZSBkZWZhdWx0IGNvbnRhaW5lclxuICAgIHRhc2tEZWZpbml0aW9uLmRlZmF1bHRDb250YWluZXI/LmFkZENvbnRhaW5lckRlcGVuZGVuY2llcyh7XG4gICAgICBjb250YWluZXI6IHNpZGVjYXIsXG4gICAgICBjb25kaXRpb246IGVjcy5Db250YWluZXJEZXBlbmRlbmN5Q29uZGl0aW9uLlNUQVJULFxuICAgIH0pXG5cbiAgICAvKlxuICAgICAqIGF3cy1vdGVsLWNvbGxlY3RvciBleHBvc2VzIHRoZXNlIHBvcnRzLCBhbmQgbW9yZTpcbiAgICAgKiAtIHVkcCAyMDAwIDogQVdTIFhSYXlcbiAgICAgKiAtIHRjcCA0MzE3IDogT3BlblRlbGVtZXRyeSBjb2xsZWN0aW9uIEdSUENcbiAgICAgKiAtIHRjcCA0MzE4IDogT3BlblRlbGVtZXRyeSBjb2xsZWN0aW9uIEhUVFBcbiAgICAgKlxuICAgICAqIFRoZXNlIGFyZSBkZWZpbmVkIGluIHRoZSB5YW1sIGNvbmZpZyBmb3IgdGhlIGNvbGxlY3Rvci5cbiAgICAgKi9cbiAgICB0YXNrRGVmaW5pdGlvbi5kZWZhdWx0Q29udGFpbmVyPy5hZGRFbnZpcm9ubWVudChcbiAgICAgIFwiQVdTX1hSQVlfREFFTU9OX0FERFJFU1NcIixcbiAgICAgIFwiaHR0cDovL2xvY2FsaG9zdDoyMDAwXCIsXG4gICAgKVxuICAgIHRhc2tEZWZpbml0aW9uLmRlZmF1bHRDb250YWluZXI/LmFkZEVudmlyb25tZW50KFxuICAgICAgXCJPVEVMX0VYUE9SVEVSX09UTFBfRU5EUE9JTlRcIixcbiAgICAgIFwiaHR0cDovL2xvY2FsaG9zdDo0MzE3XCIsXG4gICAgKVxuICAgIHRhc2tEZWZpbml0aW9uLmRlZmF1bHRDb250YWluZXI/LmFkZEVudmlyb25tZW50KFxuICAgICAgXCJPVEVMX0pBVkFBR0VOVF9FTkFCTEVEXCIsXG4gICAgICBcInRydWVcIixcbiAgICApXG5cbiAgICBpZiAoIXRhc2tEZWZpbml0aW9uLmlzRmFyZ2F0ZUNvbXBhdGlibGUpIHtcbiAgICAgIC8vIFRoaXMgZXh0ZW5zaW9uIGlzIG1hZGUgZm9yIHRoZSBGYXJnYXRlU2VydmljZSwgc28gdGhpcyBpcyBhIHJlcXVpcmVtZW50LlxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcIlRoaXMgdGFzayBkZWZpbml0aW9uIGNhbiBub3QgYmUgcmFuIG9uIGZhcmdhdGUhIFwiICtcbiAgICAgICAgICB0YXNrRGVmaW5pdGlvbi5ub2RlLmlkLFxuICAgICAgKVxuICAgIH1cbiAgfVxufVxuXG5pbnRlcmZhY2UgT3BlblRlbGVtZXRyeVBvbGljaWVzUHJvcHMge1xuICB0YXNrRGVmaW5pdGlvbjogZWNzLlRhc2tEZWZpbml0aW9uXG59XG5cbi8qKlxuICogR3JhbnRzIHRoZSBzaWRlY2FyIHBlcm1pc3Npb25zIHRvIGNyZWF0ZSBsb2dzLCBtZXRyaWNzIGFuZCBYUmF5IHRyYWNlcyBieSBleHRlbmRpbmcgdGhlIHRhc2sgcm9sZXMuXG4gKi9cbmNsYXNzIE9wZW5UZWxlbWV0cnlQb2xpY2llcyBleHRlbmRzIGNvbnN0cnVjdHMuQ29uc3RydWN0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IGNvbnN0cnVjdHMuQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJvcHM6IE9wZW5UZWxlbWV0cnlQb2xpY2llc1Byb3BzLFxuICApIHtcbiAgICBzdXBlcihzY29wZSwgaWQpXG5cbiAgICBjb25zdCBhd3NEaXN0cm9PcGVuVGVsZW1ldHJ5UG9saWN5U3RhdGVtZW50ID0gbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgcmVzb3VyY2VzOiBbXCIqXCJdLFxuICAgICAgYWN0aW9uczogW1xuICAgICAgICBcImxvZ3M6UHV0TG9nRXZlbnRzXCIsXG4gICAgICAgIFwibG9nczpDcmVhdGVMb2dHcm91cFwiLFxuICAgICAgICBcImxvZ3M6Q3JlYXRlTG9nU3RyZWFtXCIsXG4gICAgICAgIFwibG9nczpEZXNjcmliZUxvZ1N0cmVhbXNcIixcbiAgICAgICAgXCJsb2dzOkRlc2NyaWJlTG9nR3JvdXBzXCIsXG4gICAgICAgIFwibG9nczpQdXRSZXRlbnRpb25Qb2xpY3lcIixcbiAgICAgICAgXCJ4cmF5OlB1dFRyYWNlU2VnbWVudHNcIixcbiAgICAgICAgXCJ4cmF5OlB1dFRlbGVtZXRyeVJlY29yZHNcIixcbiAgICAgICAgXCJ4cmF5OkdldFNhbXBsaW5nUnVsZXNcIixcbiAgICAgICAgXCJ4cmF5OkdldFNhbXBsaW5nVGFyZ2V0c1wiLFxuICAgICAgICBcInhyYXk6R2V0U2FtcGxpbmdTdGF0aXN0aWNTdW1tYXJpZXNcIixcbiAgICAgICAgXCJjbG91ZHdhdGNoOlB1dE1ldHJpY0RhdGFcIixcbiAgICAgICAgXCJlYzI6RGVzY3JpYmVWb2x1bWVzXCIsXG4gICAgICAgIFwiZWMyOkRlc2NyaWJlVGFnc1wiLFxuICAgICAgICBcInNzbTpHZXRQYXJhbWV0ZXJzXCIsXG4gICAgICBdLFxuICAgIH0pXG5cbiAgICBwcm9wcy50YXNrRGVmaW5pdGlvbi5hZGRUb1Rhc2tSb2xlUG9saWN5KFxuICAgICAgYXdzRGlzdHJvT3BlblRlbGVtZXRyeVBvbGljeVN0YXRlbWVudCxcbiAgICApXG5cbiAgICBwcm9wcy50YXNrRGVmaW5pdGlvbi5hZGRUb0V4ZWN1dGlvblJvbGVQb2xpY3koXG4gICAgICBhd3NEaXN0cm9PcGVuVGVsZW1ldHJ5UG9saWN5U3RhdGVtZW50LFxuICAgIClcbiAgICBwcm9wcy50YXNrRGVmaW5pdGlvbi5leGVjdXRpb25Sb2xlPy5hZGRNYW5hZ2VkUG9saWN5KFxuICAgICAgaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKFwiQ2xvdWRXYXRjaExvZ3NGdWxsQWNjZXNzXCIpLFxuICAgIClcbiAgICBwcm9wcy50YXNrRGVmaW5pdGlvbi5leGVjdXRpb25Sb2xlPy5hZGRNYW5hZ2VkUG9saWN5KFxuICAgICAgaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKFwiQW1hem9uU1NNUmVhZE9ubHlBY2Nlc3NcIiksXG4gICAgKVxuICB9XG59XG5cbi8qKlxuICogVGhpcyBpcyBhIG1vZGlmaWVkIHZlcnNpb24gb2YgYC4vZXRjL2Vjcy9jb250YWluZXItaW5zaWdodHMvb3RlbC10YXNrLW1ldHJpY3MtY29uZmlnLnlhbWxgXG4gKiB3aGVyZSB3ZSBhZGQgYHJlc291cmNlX3RvX3RlbGVtZXRyeV9jb252ZXJzaW9uYCBzbyB0aGUgb3RlbCByZXNvdXJjZSBgc2VydmljZS5uYW1lYFxuICogY2FuIGJlIGFkZGVkIHRvIHRoZSBtZXRyaWMuIFRoaXMgaXMgdXNlZnVsIGJlY2F1c2UgeW91IGNhbiBmaWx0ZXIgaW4gbWV0cmljcyBiYXNlZCBvbiBzZXJ2aWNlLFxuICogaW5zdGVhZCBvZiBncm91cGluZyBlLmcuIGFsbCBzZXJ2aWNlcycgbWVtb3J5IHVzYWdlIHVuZGVyIHRoZSBzYW1lIG1ldHJpYy5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vYXdzLW90ZWwuZ2l0aHViLmlvL2RvY3Mvc2V0dXAvZWNzL2NvbmZpZy10aHJvdWdoLXNzbVxuICogQHNlZSBodHRwczovL2F3cy1vdGVsLmdpdGh1Yi5pby9kb2NzL2dldHRpbmctc3RhcnRlZC9jbG91ZHdhdGNoLW1ldHJpY3MjY2xvdWR3YXRjaC1lbWYtZXhwb3J0ZXItYXdzZW1mXG4gKi9cbmNvbnN0IGF3c090ZWxDdXN0b21Db25maWdZYW1sID0gcmVhZEZpbGVTeW5jKFxuICBwYXRoLnJlc29sdmUoXG4gICAgX19kaXJuYW1lLFxuICAgIFwiLi5cIixcbiAgICBcIi4uXCIsXG4gICAgXCJhc3NldHNcIixcbiAgICBcIm9wZW4tdGVsZW1ldHJ5XCIsXG4gICAgXCJvdGVsLWNvbGxlY3Rvci10YXNrLW1ldHJpY3MtY29uZmlnLnlhbWxcIixcbiAgKSxcbiAgXCJ1dGYtOFwiLFxuKVxuICAuc3BsaXQoXCJcXG5cIilcbiAgLmZpbHRlcigobGluZSkgPT4gIS9eXFxzKiMjLy50ZXN0KGxpbmUpKSAvLyBTa2lwIGNvbW1lbnRzIHN0YXJ0aW5nIHdpdGggIyNcbiAgLmpvaW4oXCJcXG5cIilcbiJdfQ==
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liflig/cdk",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.13.1",
|
|
4
4
|
"description": "CDK library for Liflig",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@commitlint/cli": "19.8.1",
|
|
56
56
|
"@commitlint/config-conventional": "19.8.1",
|
|
57
57
|
"@eslint/eslintrc": "3.3.1",
|
|
58
|
-
"@eslint/js": "9.
|
|
58
|
+
"@eslint/js": "9.32.0",
|
|
59
59
|
"@types/aws-lambda": "8.10.152",
|
|
60
60
|
"@types/jest": "30.0.0",
|
|
61
61
|
"@types/node": "24.1.0",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"aws-cdk-lib": "2.207.0",
|
|
66
66
|
"constructs": "10.4.2",
|
|
67
67
|
"esbuild": "0.25.8",
|
|
68
|
-
"eslint": "9.
|
|
68
|
+
"eslint": "9.32.0",
|
|
69
69
|
"eslint-config-prettier": "10.1.8",
|
|
70
70
|
"eslint-plugin-prettier": "5.5.3",
|
|
71
71
|
"husky": "9.1.7",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"semantic-release": "24.2.7",
|
|
76
76
|
"ts-jest": "29.4.0",
|
|
77
77
|
"tsx": "4.20.3",
|
|
78
|
-
"typedoc": "0.28.
|
|
78
|
+
"typedoc": "0.28.8",
|
|
79
79
|
"typescript": "5.8.3"
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|