@odigos/aws-cdk 0.0.12 → 0.0.14

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,231 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OTLP_PROTOCOL_HTTP = exports.OTLP_PROTOCOL_GRPC = void 0;
4
+ exports.evaluateAppendPattern = evaluateAppendPattern;
5
+ exports.appendSeparator = appendSeparator;
6
+ exports.languageKeyOf = languageKeyOf;
7
+ exports.recipeFor = recipeFor;
8
+ exports.sidecarCommand = sidecarCommand;
9
+ exports.fargateResourceAttributes = fargateResourceAttributes;
10
+ exports.exportTargetFor = exportTargetFor;
11
+ exports.portProtocolMismatch = portProtocolMismatch;
12
+ const fargate_1 = require("./generated/fargate");
13
+ /**
14
+ * How a language's agent is staged into an ECS Fargate task and activated in a container.
15
+ *
16
+ * A PORT of `recipeFor` / `applyInstrumentation` in the connector's ECS instrumentor
17
+ * (connectors/providers/aws/pkg/workload/instrumentor/ecs_recipes.go, ecs_inject.go). The data lives in
18
+ * ../../artifacts.json and reaches here through the generated module; the decisions live here.
19
+ *
20
+ * Equivalence with the connector is not cosmetic. Its conformance observer rebuilds each container's
21
+ * desired activation environment and compares it against what the container carries, component by
22
+ * component, so anything rendered differently here is reported to the customer as instrumentation drift
23
+ * on a stack that is in fact deployed exactly as they wrote it.
24
+ */
25
+ /** The distro placeholder for the container's own pre-Odigos value of an append-style loader variable. */
26
+ const ORIGINAL_ENV_VALUE_PLACEHOLDER = '{{ORIGINAL_ENV_VALUE}}';
27
+ /** The distro placeholder for the shared volume's mount path. */
28
+ const AGENTS_DIR_PLACEHOLDER = '{{ODIGOS_AGENTS_DIR}}';
29
+ /**
30
+ * The distro parameter for the application's runtime `major.minor`, as a Go text/template action —
31
+ * verbatim from the distro yaml so ../../artifacts.json can be diffed against it by eye. Only php and
32
+ * ruby carry it: their agents are laid down per runtime version.
33
+ */
34
+ const RUNTIME_VERSION_PLACEHOLDER = '{{.RUNTIME_VERSION_MAJOR_MINOR}}';
35
+ /** `OTEL_EXPORTER_OTLP_PROTOCOL` values. Endpoint and protocol are always decided together. */
36
+ exports.OTLP_PROTOCOL_GRPC = 'grpc';
37
+ exports.OTLP_PROTOCOL_HTTP = 'http/protobuf';
38
+ /** Standard OTLP receiver ports, used only to warn about an endpoint paired with the other protocol. */
39
+ const OTLP_DEFAULT_GRPC_PORT = '4317';
40
+ const OTLP_DEFAULT_HTTP_PORT = '4318';
41
+ /**
42
+ * Resolves an append pattern for a given pre-existing value.
43
+ *
44
+ * Port of `distro.EvaluateReplacePattern`, INCLUDING the empty-original case: with nothing to join to,
45
+ * the placeholder and its adjacent delimiter are stripped, so the result never opens with a stray space
46
+ * or colon. `PYTHONPATH=":/var/odigos/python"` would put the current working directory on `sys.path`
47
+ * ahead of the agent, which is a different program than the one intended.
48
+ */
49
+ function evaluateAppendPattern(pattern, originalValue) {
50
+ const withDir = pattern.split(AGENTS_DIR_PLACEHOLDER).join(fargate_1.FARGATE_AGENTS_DIR);
51
+ if (originalValue.trim() === '') {
52
+ return withDir.split(ORIGINAL_ENV_VALUE_PLACEHOLDER).join('').replace(/^[ :]+/, '');
53
+ }
54
+ return withDir.split(ORIGINAL_ENV_VALUE_PLACEHOLDER).join(originalValue);
55
+ }
56
+ /**
57
+ * The delimiter a pattern joins the container's own value to ours with: the character immediately after
58
+ * the original-value placeholder.
59
+ *
60
+ * DERIVED from the pattern rather than declared, because the pattern is the authority — it comes from the
61
+ * upstream distro, differs by language (a space for `JAVA_TOOL_OPTIONS`/`NODE_OPTIONS`, a colon for
62
+ * `PYTHONPATH`) and can change on somebody else's release. Assuming one would be silently destructive in
63
+ * a way nothing here would catch: a space-joined `PYTHONPATH` is one unusable path rather than two, and
64
+ * the process still starts.
65
+ */
66
+ function appendSeparator(pattern) {
67
+ const i = pattern.indexOf(ORIGINAL_ENV_VALUE_PLACEHOLDER);
68
+ if (i < 0) {
69
+ return '';
70
+ }
71
+ const rest = pattern.slice(i + ORIGINAL_ENV_VALUE_PLACEHOLDER.length);
72
+ return rest === '' ? '' : rest.charAt(0);
73
+ }
74
+ /** The canonical connector language key for an enum member. The enum's values ARE those keys. */
75
+ function languageKeyOf(language) {
76
+ return language;
77
+ }
78
+ /**
79
+ * The recipe for a language, with the runtime version rendered into the agents' paths where the language
80
+ * needs it.
81
+ *
82
+ * @param runtimeVersion the application's runtime `major.minor`. Required for php and ruby, whose agent
83
+ * files are laid down per version, and ignored by every other language.
84
+ */
85
+ function recipeFor(language, runtimeVersion) {
86
+ const key = languageKeyOf(language);
87
+ const spec = fargate_1.FARGATE_LANGUAGES[key];
88
+ if (!spec) {
89
+ // Unreachable through the enum; reachable if the generated table and the enum ever disagree.
90
+ throw new Error(`Odigos: no ECS Fargate agent recipe for language "${key}".`);
91
+ }
92
+ if (spec.requiresRuntimeVersion && !runtimeVersion) {
93
+ throw new Error(`Odigos: the ${key} agent's files are laid down per runtime version, so instrumenting a ${key} ` +
94
+ 'container needs `runtimeVersion` set to the application\'s major.minor (for example "8.3"). ' +
95
+ 'The value selects the agent path the activation environment points at, so a wrong or missing ' +
96
+ 'one leaves the container with an agent that is never loaded.');
97
+ }
98
+ // Rejected here rather than passed through: a "8.3.4" or "php8.3" would be rendered straight into
99
+ // PHP_INI_SCAN_DIR / RUBYOPT as a path that does not exist in the bundle, and the container would start
100
+ // with no agent loaded and no error anywhere near the cause.
101
+ if (runtimeVersion && !/^\d+\.\d+$/.test(runtimeVersion)) {
102
+ throw new Error(`Odigos: runtimeVersion "${runtimeVersion}" must be exactly major.minor (for example "8.3") — it ` +
103
+ 'names a directory in the agents bundle, not a full version.');
104
+ }
105
+ const staticEnv = {};
106
+ for (const [k, v] of Object.entries(spec.staticEnv)) {
107
+ staticEnv[k] = runtimeVersion ? v.split(RUNTIME_VERSION_PLACEHOLDER).join(runtimeVersion) : v;
108
+ }
109
+ return {
110
+ language: key,
111
+ agentDirs: spec.agentDirs,
112
+ staticEnv,
113
+ appendEnv: spec.appendEnv.map((a) => ({ name: a.name, pattern: a.pattern })),
114
+ otlpProtocol: spec.otlpProtocol,
115
+ protocolFixed: spec.protocolFixed,
116
+ };
117
+ }
118
+ /**
119
+ * The staging container's command: create the shared directory, then copy each language's agent
120
+ * directory out of the image into it, then exit 0.
121
+ *
122
+ * ORDER AND SPELLING ARE THE CONTRACT. There is ONE staging container per task definition however many
123
+ * languages it holds, and the connector compares its command against the union of every instrumented
124
+ * container's agent directories in ascending order. A command that differs by a space is reported as
125
+ * drift on the whole task definition, so this is sorted and rendered exactly as `sidecarCommand` in the
126
+ * connector does it.
127
+ */
128
+ function sidecarCommand(agentDirs) {
129
+ const dirs = [...new Set(agentDirs)].sort();
130
+ let script = `mkdir -p ${fargate_1.FARGATE_AGENTS_DIR}`;
131
+ for (const d of dirs) {
132
+ script += ` && cp -r ${fargate_1.FARGATE_IMAGE_AGENTS_DIR}/${d} ${fargate_1.FARGATE_AGENTS_DIR}/${d}`;
133
+ }
134
+ return ['sh', '-c', script];
135
+ }
136
+ /**
137
+ * The resource attributes every span, metric and log from an instrumented task carries. `service.name` is
138
+ * set separately, through `OTEL_SERVICE_NAME`.
139
+ *
140
+ * The region may be an unresolved token on an environment-agnostic stack, which is fine here and unlike
141
+ * the Lambda layer lookup: this value is an environment variable, so the token resolves to a `Ref` to
142
+ * `AWS::Region` and CloudFormation fills in the real region at deploy time.
143
+ */
144
+ function fargateResourceAttributes(region) {
145
+ const attrs = 'cloud.provider=aws,cloud.platform=aws_ecs';
146
+ return region ? `${attrs},cloud.region=${region}` : attrs;
147
+ }
148
+ /**
149
+ * Turns a destination's OTLP/gRPC target (`host:port`) into the URL the OpenTelemetry SDK env accepts,
150
+ * taking the scheme from the destination's TLS setting. A value that is already a URL passes through.
151
+ */
152
+ function grpcEndpointURL(endpoint, insecure) {
153
+ if (endpoint === '') {
154
+ return '';
155
+ }
156
+ if (endpoint.includes('://')) {
157
+ return endpoint;
158
+ }
159
+ return `${insecure === true ? 'http' : 'https'}://${endpoint}`;
160
+ }
161
+ /**
162
+ * Resolves the endpoint and protocol for one recipe against one destination.
163
+ *
164
+ * Port of `exportTargetFor`. A Fargate task has no node-local collector — unlike Lambda, where the SDK
165
+ * exports to a collector in the same sandbox — so the agent exports OTLP straight to the destination, and
166
+ * which transport it can use is a property of the agent as much as of the destination.
167
+ *
168
+ * Each agent's PREFERRED transport is taken when the destination offers it. When it does not, an agent
169
+ * whose community SDK pins the protocol (php, ruby) cannot be switched and throws; every other agent
170
+ * honours `OTEL_EXPORTER_OTLP_PROTOCOL` and falls back to whichever transport exists.
171
+ */
172
+ function exportTargetFor(recipe, dest) {
173
+ const grpcURL = grpcEndpointURL(dest.endpoint ?? '', dest.insecure);
174
+ const httpURL = dest.httpEndpoint ?? '';
175
+ if (recipe.otlpProtocol === exports.OTLP_PROTOCOL_HTTP && httpURL !== '') {
176
+ return { endpoint: httpURL, protocol: exports.OTLP_PROTOCOL_HTTP };
177
+ }
178
+ if (recipe.otlpProtocol === exports.OTLP_PROTOCOL_GRPC && grpcURL !== '') {
179
+ return { endpoint: grpcURL, protocol: exports.OTLP_PROTOCOL_GRPC };
180
+ }
181
+ if (recipe.protocolFixed) {
182
+ throw new Error(`Odigos: the ${recipe.language} agent exports OTLP over ${recipe.otlpProtocol} only — its community ` +
183
+ 'SDK cannot be switched to the other transport — but the destination configures no ' +
184
+ `${recipe.otlpProtocol === exports.OTLP_PROTOCOL_HTTP ? '`httpEndpoint`' : '`endpoint`'}. ` +
185
+ 'Configure one, or leave this container uninstrumented.');
186
+ }
187
+ if (httpURL !== '') {
188
+ return { endpoint: httpURL, protocol: exports.OTLP_PROTOCOL_HTTP };
189
+ }
190
+ if (grpcURL !== '') {
191
+ return { endpoint: grpcURL, protocol: exports.OTLP_PROTOCOL_GRPC };
192
+ }
193
+ throw new Error('Odigos destination has neither `endpoint` (OTLP/gRPC) nor `httpEndpoint` (OTLP/HTTP), so an ' +
194
+ 'instrumented Fargate task would have nowhere to export. Unlike Lambda, a Fargate task has no ' +
195
+ 'in-sandbox collector to buffer for it — the agent exports to this destination directly.');
196
+ }
197
+ /** The port of a `scheme://host:port[/path]` endpoint, or "" when it names none. */
198
+ function endpointPort(endpoint) {
199
+ let rest = endpoint;
200
+ const scheme = rest.indexOf('://');
201
+ if (scheme >= 0) {
202
+ rest = rest.slice(scheme + 3);
203
+ }
204
+ const pathStart = rest.search(/[/?]/);
205
+ if (pathStart >= 0) {
206
+ rest = rest.slice(0, pathStart);
207
+ }
208
+ const colon = rest.lastIndexOf(':');
209
+ return colon < 0 ? '' : rest.slice(colon + 1);
210
+ }
211
+ /**
212
+ * A warning when an endpoint's port is the well-known port of the OTHER OTLP protocol, or "" when the
213
+ * pairing looks right — including a non-standard port, which cannot be judged.
214
+ *
215
+ * Worth a synth-time warning because the runtime symptom is a connection reset mid-export, which points
216
+ * nowhere near the cause: an HTTP request against an HTTP/2 gRPC listener, or the reverse.
217
+ */
218
+ function portProtocolMismatch(endpoint, protocol) {
219
+ const port = endpointPort(endpoint);
220
+ if (protocol === exports.OTLP_PROTOCOL_HTTP && port === OTLP_DEFAULT_GRPC_PORT) {
221
+ return (`endpoint ${endpoint} is on ${OTLP_DEFAULT_GRPC_PORT}, the standard OTLP/gRPC port, but this agent ` +
222
+ `exports over ${exports.OTLP_PROTOCOL_HTTP}; exports will fail as a connection reset. Point it at the ` +
223
+ `OTLP/HTTP port (${OTLP_DEFAULT_HTTP_PORT}).`);
224
+ }
225
+ if (protocol === exports.OTLP_PROTOCOL_GRPC && port === OTLP_DEFAULT_HTTP_PORT) {
226
+ return (`endpoint ${endpoint} is on ${OTLP_DEFAULT_HTTP_PORT}, the standard OTLP/HTTP port, but this agent ` +
227
+ `exports over gRPC; exports will fail. Point it at the OTLP/gRPC port (${OTLP_DEFAULT_GRPC_PORT}).`);
228
+ }
229
+ return '';
230
+ }
231
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFyZ2F0ZS1yZWNpcGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ZhcmdhdGUtcmVjaXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUE0REEsc0RBTUM7QUFZRCwwQ0FPQztBQW1CRCxzQ0FFQztBQVNELDhCQXNDQztBQVlELHdDQU9DO0FBVUQsOERBR0M7QUFtQ0QsMENBNkJDO0FBd0JELG9EQWdCQztBQWpTRCxpREFJNkI7QUFHN0I7Ozs7Ozs7Ozs7O0dBV0c7QUFFSCwwR0FBMEc7QUFDMUcsTUFBTSw4QkFBOEIsR0FBRyx3QkFBd0IsQ0FBQztBQUVoRSxpRUFBaUU7QUFDakUsTUFBTSxzQkFBc0IsR0FBRyx1QkFBdUIsQ0FBQztBQUV2RDs7OztHQUlHO0FBQ0gsTUFBTSwyQkFBMkIsR0FBRyxrQ0FBa0MsQ0FBQztBQUV2RSwrRkFBK0Y7QUFDbEYsUUFBQSxrQkFBa0IsR0FBRyxNQUFNLENBQUM7QUFDNUIsUUFBQSxrQkFBa0IsR0FBRyxlQUFlLENBQUM7QUFFbEQsd0dBQXdHO0FBQ3hHLE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFDO0FBQ3RDLE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFDO0FBYXRDOzs7Ozs7O0dBT0c7QUFDSCxTQUFnQixxQkFBcUIsQ0FBQyxPQUFlLEVBQUUsYUFBcUI7SUFDMUUsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLElBQUksQ0FBQyw0QkFBa0IsQ0FBQyxDQUFDO0lBQy9FLElBQUksYUFBYSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDO1FBQ2hDLE9BQU8sT0FBTyxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3RGLENBQUM7SUFDRCxPQUFPLE9BQU8sQ0FBQyxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDM0UsQ0FBQztBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILFNBQWdCLGVBQWUsQ0FBQyxPQUFlO0lBQzdDLE1BQU0sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsOEJBQThCLENBQUMsQ0FBQztJQUMxRCxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNWLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUNELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLDhCQUE4QixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RFLE9BQU8sSUFBSSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzNDLENBQUM7QUFrQkQsaUdBQWlHO0FBQ2pHLFNBQWdCLGFBQWEsQ0FBQyxRQUErQjtJQUMzRCxPQUFPLFFBQVEsQ0FBQztBQUNsQixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsU0FBZ0IsU0FBUyxDQUFDLFFBQStCLEVBQUUsY0FBdUI7SUFDaEYsTUFBTSxHQUFHLEdBQUcsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3BDLE1BQU0sSUFBSSxHQUFHLDJCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3BDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNWLDZGQUE2RjtRQUM3RixNQUFNLElBQUksS0FBSyxDQUFDLHFEQUFxRCxHQUFHLElBQUksQ0FBQyxDQUFDO0lBQ2hGLENBQUM7SUFDRCxJQUFJLElBQUksQ0FBQyxzQkFBc0IsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ25ELE1BQU0sSUFBSSxLQUFLLENBQ2IsZUFBZSxHQUFHLHdFQUF3RSxHQUFHLEdBQUc7WUFDOUYsOEZBQThGO1lBQzlGLCtGQUErRjtZQUMvRiw4REFBOEQsQ0FDakUsQ0FBQztJQUNKLENBQUM7SUFDRCxrR0FBa0c7SUFDbEcsd0dBQXdHO0lBQ3hHLDZEQUE2RDtJQUM3RCxJQUFJLGNBQWMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztRQUN6RCxNQUFNLElBQUksS0FBSyxDQUNiLDJCQUEyQixjQUFjLHlEQUF5RDtZQUNoRyw2REFBNkQsQ0FDaEUsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNLFNBQVMsR0FBOEIsRUFBRSxDQUFDO0lBQ2hELEtBQUssTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ3BELFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNoRyxDQUFDO0lBRUQsT0FBTztRQUNMLFFBQVEsRUFBRSxHQUFHO1FBQ2IsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO1FBQ3pCLFNBQVM7UUFDVCxTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDNUUsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO1FBQy9CLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYTtLQUNsQyxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILFNBQWdCLGNBQWMsQ0FBQyxTQUFtQjtJQUNoRCxNQUFNLElBQUksR0FBRyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUM1QyxJQUFJLE1BQU0sR0FBRyxZQUFZLDRCQUFrQixFQUFFLENBQUM7SUFDOUMsS0FBSyxNQUFNLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUNyQixNQUFNLElBQUksYUFBYSxrQ0FBd0IsSUFBSSxDQUFDLElBQUksNEJBQWtCLElBQUksQ0FBQyxFQUFFLENBQUM7SUFDcEYsQ0FBQztJQUNELE9BQU8sQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQzlCLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsU0FBZ0IseUJBQXlCLENBQUMsTUFBYztJQUN0RCxNQUFNLEtBQUssR0FBRywyQ0FBMkMsQ0FBQztJQUMxRCxPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLGlCQUFpQixNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0FBQzVELENBQUM7QUFVRDs7O0dBR0c7QUFDSCxTQUFTLGVBQWUsQ0FBQyxRQUFnQixFQUFFLFFBQWtCO0lBQzNELElBQUksUUFBUSxLQUFLLEVBQUUsRUFBRSxDQUFDO1FBQ3BCLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUNELElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzdCLE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFDRCxPQUFPLEdBQUcsUUFBUSxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLE1BQU0sUUFBUSxFQUFFLENBQUM7QUFDakUsQ0FBQztBQUVEOzs7Ozs7Ozs7O0dBVUc7QUFDSCxTQUFnQixlQUFlLENBQUMsTUFBcUIsRUFBRSxJQUF1QjtJQUM1RSxNQUFNLE9BQU8sR0FBRyxlQUFlLENBQUMsSUFBSSxDQUFDLFFBQVEsSUFBSSxFQUFFLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3BFLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxZQUFZLElBQUksRUFBRSxDQUFDO0lBRXhDLElBQUksTUFBTSxDQUFDLFlBQVksS0FBSywwQkFBa0IsSUFBSSxPQUFPLEtBQUssRUFBRSxFQUFFLENBQUM7UUFDakUsT0FBTyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLDBCQUFrQixFQUFFLENBQUM7SUFDN0QsQ0FBQztJQUNELElBQUksTUFBTSxDQUFDLFlBQVksS0FBSywwQkFBa0IsSUFBSSxPQUFPLEtBQUssRUFBRSxFQUFFLENBQUM7UUFDakUsT0FBTyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLDBCQUFrQixFQUFFLENBQUM7SUFDN0QsQ0FBQztJQUNELElBQUksTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sSUFBSSxLQUFLLENBQ2IsZUFBZSxNQUFNLENBQUMsUUFBUSw0QkFBNEIsTUFBTSxDQUFDLFlBQVksd0JBQXdCO1lBQ25HLG9GQUFvRjtZQUNwRixHQUFHLE1BQU0sQ0FBQyxZQUFZLEtBQUssMEJBQWtCLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxZQUFZLElBQUk7WUFDbkYsd0RBQXdELENBQzNELENBQUM7SUFDSixDQUFDO0lBQ0QsSUFBSSxPQUFPLEtBQUssRUFBRSxFQUFFLENBQUM7UUFDbkIsT0FBTyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLDBCQUFrQixFQUFFLENBQUM7SUFDN0QsQ0FBQztJQUNELElBQUksT0FBTyxLQUFLLEVBQUUsRUFBRSxDQUFDO1FBQ25CLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSwwQkFBa0IsRUFBRSxDQUFDO0lBQzdELENBQUM7SUFDRCxNQUFNLElBQUksS0FBSyxDQUNiLDhGQUE4RjtRQUM1RiwrRkFBK0Y7UUFDL0YseUZBQXlGLENBQzVGLENBQUM7QUFDSixDQUFDO0FBRUQsb0ZBQW9GO0FBQ3BGLFNBQVMsWUFBWSxDQUFDLFFBQWdCO0lBQ3BDLElBQUksSUFBSSxHQUFHLFFBQVEsQ0FBQztJQUNwQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ25DLElBQUksTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ2hCLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBQ0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN0QyxJQUFJLFNBQVMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUNuQixJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUNELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDcEMsT0FBTyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ2hELENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFnQixvQkFBb0IsQ0FBQyxRQUFnQixFQUFFLFFBQWdCO0lBQ3JFLE1BQU0sSUFBSSxHQUFHLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNwQyxJQUFJLFFBQVEsS0FBSywwQkFBa0IsSUFBSSxJQUFJLEtBQUssc0JBQXNCLEVBQUUsQ0FBQztRQUN2RSxPQUFPLENBQ0wsWUFBWSxRQUFRLFVBQVUsc0JBQXNCLGdEQUFnRDtZQUNwRyxnQkFBZ0IsMEJBQWtCLDZEQUE2RDtZQUMvRixtQkFBbUIsc0JBQXNCLElBQUksQ0FDOUMsQ0FBQztJQUNKLENBQUM7SUFDRCxJQUFJLFFBQVEsS0FBSywwQkFBa0IsSUFBSSxJQUFJLEtBQUssc0JBQXNCLEVBQUUsQ0FBQztRQUN2RSxPQUFPLENBQ0wsWUFBWSxRQUFRLFVBQVUsc0JBQXNCLGdEQUFnRDtZQUNwRyx5RUFBeUUsc0JBQXNCLElBQUksQ0FDcEcsQ0FBQztJQUNKLENBQUM7SUFDRCxPQUFPLEVBQUUsQ0FBQztBQUNaLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBGQVJHQVRFX0FHRU5UU19ESVIsXG4gIEZBUkdBVEVfSU1BR0VfQUdFTlRTX0RJUixcbiAgRkFSR0FURV9MQU5HVUFHRVMsXG59IGZyb20gJy4vZ2VuZXJhdGVkL2ZhcmdhdGUnO1xuaW1wb3J0IHsgT2RpZ29zRGVzdGluYXRpb24sIE9kaWdvc0ZhcmdhdGVMYW5ndWFnZSB9IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIEhvdyBhIGxhbmd1YWdlJ3MgYWdlbnQgaXMgc3RhZ2VkIGludG8gYW4gRUNTIEZhcmdhdGUgdGFzayBhbmQgYWN0aXZhdGVkIGluIGEgY29udGFpbmVyLlxuICpcbiAqIEEgUE9SVCBvZiBgcmVjaXBlRm9yYCAvIGBhcHBseUluc3RydW1lbnRhdGlvbmAgaW4gdGhlIGNvbm5lY3RvcidzIEVDUyBpbnN0cnVtZW50b3JcbiAqIChjb25uZWN0b3JzL3Byb3ZpZGVycy9hd3MvcGtnL3dvcmtsb2FkL2luc3RydW1lbnRvci9lY3NfcmVjaXBlcy5nbywgZWNzX2luamVjdC5nbykuIFRoZSBkYXRhIGxpdmVzIGluXG4gKiAuLi8uLi9hcnRpZmFjdHMuanNvbiBhbmQgcmVhY2hlcyBoZXJlIHRocm91Z2ggdGhlIGdlbmVyYXRlZCBtb2R1bGU7IHRoZSBkZWNpc2lvbnMgbGl2ZSBoZXJlLlxuICpcbiAqIEVxdWl2YWxlbmNlIHdpdGggdGhlIGNvbm5lY3RvciBpcyBub3QgY29zbWV0aWMuIEl0cyBjb25mb3JtYW5jZSBvYnNlcnZlciByZWJ1aWxkcyBlYWNoIGNvbnRhaW5lcidzXG4gKiBkZXNpcmVkIGFjdGl2YXRpb24gZW52aXJvbm1lbnQgYW5kIGNvbXBhcmVzIGl0IGFnYWluc3Qgd2hhdCB0aGUgY29udGFpbmVyIGNhcnJpZXMsIGNvbXBvbmVudCBieVxuICogY29tcG9uZW50LCBzbyBhbnl0aGluZyByZW5kZXJlZCBkaWZmZXJlbnRseSBoZXJlIGlzIHJlcG9ydGVkIHRvIHRoZSBjdXN0b21lciBhcyBpbnN0cnVtZW50YXRpb24gZHJpZnRcbiAqIG9uIGEgc3RhY2sgdGhhdCBpcyBpbiBmYWN0IGRlcGxveWVkIGV4YWN0bHkgYXMgdGhleSB3cm90ZSBpdC5cbiAqL1xuXG4vKiogVGhlIGRpc3RybyBwbGFjZWhvbGRlciBmb3IgdGhlIGNvbnRhaW5lcidzIG93biBwcmUtT2RpZ29zIHZhbHVlIG9mIGFuIGFwcGVuZC1zdHlsZSBsb2FkZXIgdmFyaWFibGUuICovXG5jb25zdCBPUklHSU5BTF9FTlZfVkFMVUVfUExBQ0VIT0xERVIgPSAne3tPUklHSU5BTF9FTlZfVkFMVUV9fSc7XG5cbi8qKiBUaGUgZGlzdHJvIHBsYWNlaG9sZGVyIGZvciB0aGUgc2hhcmVkIHZvbHVtZSdzIG1vdW50IHBhdGguICovXG5jb25zdCBBR0VOVFNfRElSX1BMQUNFSE9MREVSID0gJ3t7T0RJR09TX0FHRU5UU19ESVJ9fSc7XG5cbi8qKlxuICogVGhlIGRpc3RybyBwYXJhbWV0ZXIgZm9yIHRoZSBhcHBsaWNhdGlvbidzIHJ1bnRpbWUgYG1ham9yLm1pbm9yYCwgYXMgYSBHbyB0ZXh0L3RlbXBsYXRlIGFjdGlvbiDigJRcbiAqIHZlcmJhdGltIGZyb20gdGhlIGRpc3RybyB5YW1sIHNvIC4uLy4uL2FydGlmYWN0cy5qc29uIGNhbiBiZSBkaWZmZWQgYWdhaW5zdCBpdCBieSBleWUuIE9ubHkgcGhwIGFuZFxuICogcnVieSBjYXJyeSBpdDogdGhlaXIgYWdlbnRzIGFyZSBsYWlkIGRvd24gcGVyIHJ1bnRpbWUgdmVyc2lvbi5cbiAqL1xuY29uc3QgUlVOVElNRV9WRVJTSU9OX1BMQUNFSE9MREVSID0gJ3t7LlJVTlRJTUVfVkVSU0lPTl9NQUpPUl9NSU5PUn19JztcblxuLyoqIGBPVEVMX0VYUE9SVEVSX09UTFBfUFJPVE9DT0xgIHZhbHVlcy4gRW5kcG9pbnQgYW5kIHByb3RvY29sIGFyZSBhbHdheXMgZGVjaWRlZCB0b2dldGhlci4gKi9cbmV4cG9ydCBjb25zdCBPVExQX1BST1RPQ09MX0dSUEMgPSAnZ3JwYyc7XG5leHBvcnQgY29uc3QgT1RMUF9QUk9UT0NPTF9IVFRQID0gJ2h0dHAvcHJvdG9idWYnO1xuXG4vKiogU3RhbmRhcmQgT1RMUCByZWNlaXZlciBwb3J0cywgdXNlZCBvbmx5IHRvIHdhcm4gYWJvdXQgYW4gZW5kcG9pbnQgcGFpcmVkIHdpdGggdGhlIG90aGVyIHByb3RvY29sLiAqL1xuY29uc3QgT1RMUF9ERUZBVUxUX0dSUENfUE9SVCA9ICc0MzE3JztcbmNvbnN0IE9UTFBfREVGQVVMVF9IVFRQX1BPUlQgPSAnNDMxOCc7XG5cbi8qKlxuICogQW4gYXBwZW5kLXN0eWxlIGxvYWRlciB2YXJpYWJsZSDigJQgYEpBVkFfVE9PTF9PUFRJT05TYCwgYE5PREVfT1BUSU9OU2AsIGBQWVRIT05QQVRIYCDigJQga2VwdCBhcyBpdHNcbiAqIHBhdHRlcm4gcmF0aGVyIHRoYW4gYSBmaW5pc2hlZCB2YWx1ZSwgYmVjYXVzZSB0aGUgdmFsdWUgZGVwZW5kcyBvbiB3aGF0IHRoZSBjb250YWluZXIgYWxyZWFkeSBjYXJyaWVzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEZhcmdhdGVBcHBlbmRFbnZWYXIge1xuICAvKiogVmFyaWFibGUgbmFtZS4gKi9cbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICAvKiogVGhlIGRpc3RybydzIFJlcGxhY2VQYXR0ZXJuLCBwbGFjZWhvbGRlcnMgdW5yZXNvbHZlZC4gKi9cbiAgcmVhZG9ubHkgcGF0dGVybjogc3RyaW5nO1xufVxuXG4vKipcbiAqIFJlc29sdmVzIGFuIGFwcGVuZCBwYXR0ZXJuIGZvciBhIGdpdmVuIHByZS1leGlzdGluZyB2YWx1ZS5cbiAqXG4gKiBQb3J0IG9mIGBkaXN0cm8uRXZhbHVhdGVSZXBsYWNlUGF0dGVybmAsIElOQ0xVRElORyB0aGUgZW1wdHktb3JpZ2luYWwgY2FzZTogd2l0aCBub3RoaW5nIHRvIGpvaW4gdG8sXG4gKiB0aGUgcGxhY2Vob2xkZXIgYW5kIGl0cyBhZGphY2VudCBkZWxpbWl0ZXIgYXJlIHN0cmlwcGVkLCBzbyB0aGUgcmVzdWx0IG5ldmVyIG9wZW5zIHdpdGggYSBzdHJheSBzcGFjZVxuICogb3IgY29sb24uIGBQWVRIT05QQVRIPVwiOi92YXIvb2RpZ29zL3B5dGhvblwiYCB3b3VsZCBwdXQgdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3Rvcnkgb24gYHN5cy5wYXRoYFxuICogYWhlYWQgb2YgdGhlIGFnZW50LCB3aGljaCBpcyBhIGRpZmZlcmVudCBwcm9ncmFtIHRoYW4gdGhlIG9uZSBpbnRlbmRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV2YWx1YXRlQXBwZW5kUGF0dGVybihwYXR0ZXJuOiBzdHJpbmcsIG9yaWdpbmFsVmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHdpdGhEaXIgPSBwYXR0ZXJuLnNwbGl0KEFHRU5UU19ESVJfUExBQ0VIT0xERVIpLmpvaW4oRkFSR0FURV9BR0VOVFNfRElSKTtcbiAgaWYgKG9yaWdpbmFsVmFsdWUudHJpbSgpID09PSAnJykge1xuICAgIHJldHVybiB3aXRoRGlyLnNwbGl0KE9SSUdJTkFMX0VOVl9WQUxVRV9QTEFDRUhPTERFUikuam9pbignJykucmVwbGFjZSgvXlsgOl0rLywgJycpO1xuICB9XG4gIHJldHVybiB3aXRoRGlyLnNwbGl0KE9SSUdJTkFMX0VOVl9WQUxVRV9QTEFDRUhPTERFUikuam9pbihvcmlnaW5hbFZhbHVlKTtcbn1cblxuLyoqXG4gKiBUaGUgZGVsaW1pdGVyIGEgcGF0dGVybiBqb2lucyB0aGUgY29udGFpbmVyJ3Mgb3duIHZhbHVlIHRvIG91cnMgd2l0aDogdGhlIGNoYXJhY3RlciBpbW1lZGlhdGVseSBhZnRlclxuICogdGhlIG9yaWdpbmFsLXZhbHVlIHBsYWNlaG9sZGVyLlxuICpcbiAqIERFUklWRUQgZnJvbSB0aGUgcGF0dGVybiByYXRoZXIgdGhhbiBkZWNsYXJlZCwgYmVjYXVzZSB0aGUgcGF0dGVybiBpcyB0aGUgYXV0aG9yaXR5IOKAlCBpdCBjb21lcyBmcm9tIHRoZVxuICogdXBzdHJlYW0gZGlzdHJvLCBkaWZmZXJzIGJ5IGxhbmd1YWdlIChhIHNwYWNlIGZvciBgSkFWQV9UT09MX09QVElPTlNgL2BOT0RFX09QVElPTlNgLCBhIGNvbG9uIGZvclxuICogYFBZVEhPTlBBVEhgKSBhbmQgY2FuIGNoYW5nZSBvbiBzb21lYm9keSBlbHNlJ3MgcmVsZWFzZS4gQXNzdW1pbmcgb25lIHdvdWxkIGJlIHNpbGVudGx5IGRlc3RydWN0aXZlIGluXG4gKiBhIHdheSBub3RoaW5nIGhlcmUgd291bGQgY2F0Y2g6IGEgc3BhY2Utam9pbmVkIGBQWVRIT05QQVRIYCBpcyBvbmUgdW51c2FibGUgcGF0aCByYXRoZXIgdGhhbiB0d28sIGFuZFxuICogdGhlIHByb2Nlc3Mgc3RpbGwgc3RhcnRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwZW5kU2VwYXJhdG9yKHBhdHRlcm46IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGkgPSBwYXR0ZXJuLmluZGV4T2YoT1JJR0lOQUxfRU5WX1ZBTFVFX1BMQUNFSE9MREVSKTtcbiAgaWYgKGkgPCAwKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIGNvbnN0IHJlc3QgPSBwYXR0ZXJuLnNsaWNlKGkgKyBPUklHSU5BTF9FTlZfVkFMVUVfUExBQ0VIT0xERVIubGVuZ3RoKTtcbiAgcmV0dXJuIHJlc3QgPT09ICcnID8gJycgOiByZXN0LmNoYXJBdCgwKTtcbn1cblxuLyoqIE9uZSBsYW5ndWFnZSdzIHN0YWdpbmcgYW5kIGFjdGl2YXRpb24sIHdpdGggZXZlcnkgcGxhdGZvcm0tc3VwcGxpZWQgcGFyYW1ldGVyIGFscmVhZHkgcmVuZGVyZWQuICovXG5leHBvcnQgaW50ZXJmYWNlIEZhcmdhdGVSZWNpcGUge1xuICAvKiogQ2Fub25pY2FsIGxhbmd1YWdlIGtleSwgYW5kIHRoZSB2YWx1ZSByZWNvcmRlZCBpbiB0aGUgYE9ESUdPU19JQUNgIG1hcmtlcidzIGBsYW5nYC4gKi9cbiAgcmVhZG9ubHkgbGFuZ3VhZ2U6IHN0cmluZztcbiAgLyoqIERpcmVjdG9yaWVzIHVuZGVyIHRoZSBhZ2VudHMgaW1hZ2UgdGhlIHN0YWdpbmcgY29udGFpbmVyIGNvcGllcyBpbnRvIHRoZSBzaGFyZWQgdm9sdW1lLiAqL1xuICByZWFkb25seSBhZ2VudERpcnM6IHN0cmluZ1tdO1xuICAvKiogQWN0aXZhdGlvbiB2YXJpYWJsZXMgc2V0IG91dHJpZ2h0LiAqL1xuICByZWFkb25seSBzdGF0aWNFbnY6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH07XG4gIC8qKiBBY3RpdmF0aW9uIHZhcmlhYmxlcyBvdXIgZnJhZ21lbnQgaXMgYXBwZW5kZWQgdG8uICovXG4gIHJlYWRvbmx5IGFwcGVuZEVudjogRmFyZ2F0ZUFwcGVuZEVudlZhcltdO1xuICAvKiogVGhlIHRyYW5zcG9ydCB0aGlzIGFnZW50IHByZWZlcnMuICovXG4gIHJlYWRvbmx5IG90bHBQcm90b2NvbDogc3RyaW5nO1xuICAvKiogV2hldGhlciB0aGUgYWdlbnQgY2FuIHNwZWFrIG9ubHkgYG90bHBQcm90b2NvbGAgYW5kIGNhbm5vdCBiZSBzd2l0Y2hlZCB0byB0aGUgb3RoZXIgdHJhbnNwb3J0LiAqL1xuICByZWFkb25seSBwcm90b2NvbEZpeGVkOiBib29sZWFuO1xufVxuXG4vKiogVGhlIGNhbm9uaWNhbCBjb25uZWN0b3IgbGFuZ3VhZ2Uga2V5IGZvciBhbiBlbnVtIG1lbWJlci4gVGhlIGVudW0ncyB2YWx1ZXMgQVJFIHRob3NlIGtleXMuICovXG5leHBvcnQgZnVuY3Rpb24gbGFuZ3VhZ2VLZXlPZihsYW5ndWFnZTogT2RpZ29zRmFyZ2F0ZUxhbmd1YWdlKTogc3RyaW5nIHtcbiAgcmV0dXJuIGxhbmd1YWdlO1xufVxuXG4vKipcbiAqIFRoZSByZWNpcGUgZm9yIGEgbGFuZ3VhZ2UsIHdpdGggdGhlIHJ1bnRpbWUgdmVyc2lvbiByZW5kZXJlZCBpbnRvIHRoZSBhZ2VudHMnIHBhdGhzIHdoZXJlIHRoZSBsYW5ndWFnZVxuICogbmVlZHMgaXQuXG4gKlxuICogQHBhcmFtIHJ1bnRpbWVWZXJzaW9uIHRoZSBhcHBsaWNhdGlvbidzIHJ1bnRpbWUgYG1ham9yLm1pbm9yYC4gUmVxdWlyZWQgZm9yIHBocCBhbmQgcnVieSwgd2hvc2UgYWdlbnRcbiAqIGZpbGVzIGFyZSBsYWlkIGRvd24gcGVyIHZlcnNpb24sIGFuZCBpZ25vcmVkIGJ5IGV2ZXJ5IG90aGVyIGxhbmd1YWdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjaXBlRm9yKGxhbmd1YWdlOiBPZGlnb3NGYXJnYXRlTGFuZ3VhZ2UsIHJ1bnRpbWVWZXJzaW9uPzogc3RyaW5nKTogRmFyZ2F0ZVJlY2lwZSB7XG4gIGNvbnN0IGtleSA9IGxhbmd1YWdlS2V5T2YobGFuZ3VhZ2UpO1xuICBjb25zdCBzcGVjID0gRkFSR0FURV9MQU5HVUFHRVNba2V5XTtcbiAgaWYgKCFzcGVjKSB7XG4gICAgLy8gVW5yZWFjaGFibGUgdGhyb3VnaCB0aGUgZW51bTsgcmVhY2hhYmxlIGlmIHRoZSBnZW5lcmF0ZWQgdGFibGUgYW5kIHRoZSBlbnVtIGV2ZXIgZGlzYWdyZWUuXG4gICAgdGhyb3cgbmV3IEVycm9yKGBPZGlnb3M6IG5vIEVDUyBGYXJnYXRlIGFnZW50IHJlY2lwZSBmb3IgbGFuZ3VhZ2UgXCIke2tleX1cIi5gKTtcbiAgfVxuICBpZiAoc3BlYy5yZXF1aXJlc1J1bnRpbWVWZXJzaW9uICYmICFydW50aW1lVmVyc2lvbikge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBPZGlnb3M6IHRoZSAke2tleX0gYWdlbnQncyBmaWxlcyBhcmUgbGFpZCBkb3duIHBlciBydW50aW1lIHZlcnNpb24sIHNvIGluc3RydW1lbnRpbmcgYSAke2tleX0gYCArXG4gICAgICAgICdjb250YWluZXIgbmVlZHMgYHJ1bnRpbWVWZXJzaW9uYCBzZXQgdG8gdGhlIGFwcGxpY2F0aW9uXFwncyBtYWpvci5taW5vciAoZm9yIGV4YW1wbGUgXCI4LjNcIikuICcgK1xuICAgICAgICAnVGhlIHZhbHVlIHNlbGVjdHMgdGhlIGFnZW50IHBhdGggdGhlIGFjdGl2YXRpb24gZW52aXJvbm1lbnQgcG9pbnRzIGF0LCBzbyBhIHdyb25nIG9yIG1pc3NpbmcgJyArXG4gICAgICAgICdvbmUgbGVhdmVzIHRoZSBjb250YWluZXIgd2l0aCBhbiBhZ2VudCB0aGF0IGlzIG5ldmVyIGxvYWRlZC4nLFxuICAgICk7XG4gIH1cbiAgLy8gUmVqZWN0ZWQgaGVyZSByYXRoZXIgdGhhbiBwYXNzZWQgdGhyb3VnaDogYSBcIjguMy40XCIgb3IgXCJwaHA4LjNcIiB3b3VsZCBiZSByZW5kZXJlZCBzdHJhaWdodCBpbnRvXG4gIC8vIFBIUF9JTklfU0NBTl9ESVIgLyBSVUJZT1BUIGFzIGEgcGF0aCB0aGF0IGRvZXMgbm90IGV4aXN0IGluIHRoZSBidW5kbGUsIGFuZCB0aGUgY29udGFpbmVyIHdvdWxkIHN0YXJ0XG4gIC8vIHdpdGggbm8gYWdlbnQgbG9hZGVkIGFuZCBubyBlcnJvciBhbnl3aGVyZSBuZWFyIHRoZSBjYXVzZS5cbiAgaWYgKHJ1bnRpbWVWZXJzaW9uICYmICEvXlxcZCtcXC5cXGQrJC8udGVzdChydW50aW1lVmVyc2lvbikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgT2RpZ29zOiBydW50aW1lVmVyc2lvbiBcIiR7cnVudGltZVZlcnNpb259XCIgbXVzdCBiZSBleGFjdGx5IG1ham9yLm1pbm9yIChmb3IgZXhhbXBsZSBcIjguM1wiKSDigJQgaXQgYCArXG4gICAgICAgICduYW1lcyBhIGRpcmVjdG9yeSBpbiB0aGUgYWdlbnRzIGJ1bmRsZSwgbm90IGEgZnVsbCB2ZXJzaW9uLicsXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IHN0YXRpY0VudjogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuICBmb3IgKGNvbnN0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyhzcGVjLnN0YXRpY0VudikpIHtcbiAgICBzdGF0aWNFbnZba10gPSBydW50aW1lVmVyc2lvbiA/IHYuc3BsaXQoUlVOVElNRV9WRVJTSU9OX1BMQUNFSE9MREVSKS5qb2luKHJ1bnRpbWVWZXJzaW9uKSA6IHY7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGxhbmd1YWdlOiBrZXksXG4gICAgYWdlbnREaXJzOiBzcGVjLmFnZW50RGlycyxcbiAgICBzdGF0aWNFbnYsXG4gICAgYXBwZW5kRW52OiBzcGVjLmFwcGVuZEVudi5tYXAoKGEpID0+ICh7IG5hbWU6IGEubmFtZSwgcGF0dGVybjogYS5wYXR0ZXJuIH0pKSxcbiAgICBvdGxwUHJvdG9jb2w6IHNwZWMub3RscFByb3RvY29sLFxuICAgIHByb3RvY29sRml4ZWQ6IHNwZWMucHJvdG9jb2xGaXhlZCxcbiAgfTtcbn1cblxuLyoqXG4gKiBUaGUgc3RhZ2luZyBjb250YWluZXIncyBjb21tYW5kOiBjcmVhdGUgdGhlIHNoYXJlZCBkaXJlY3RvcnksIHRoZW4gY29weSBlYWNoIGxhbmd1YWdlJ3MgYWdlbnRcbiAqIGRpcmVjdG9yeSBvdXQgb2YgdGhlIGltYWdlIGludG8gaXQsIHRoZW4gZXhpdCAwLlxuICpcbiAqIE9SREVSIEFORCBTUEVMTElORyBBUkUgVEhFIENPTlRSQUNULiBUaGVyZSBpcyBPTkUgc3RhZ2luZyBjb250YWluZXIgcGVyIHRhc2sgZGVmaW5pdGlvbiBob3dldmVyIG1hbnlcbiAqIGxhbmd1YWdlcyBpdCBob2xkcywgYW5kIHRoZSBjb25uZWN0b3IgY29tcGFyZXMgaXRzIGNvbW1hbmQgYWdhaW5zdCB0aGUgdW5pb24gb2YgZXZlcnkgaW5zdHJ1bWVudGVkXG4gKiBjb250YWluZXIncyBhZ2VudCBkaXJlY3RvcmllcyBpbiBhc2NlbmRpbmcgb3JkZXIuIEEgY29tbWFuZCB0aGF0IGRpZmZlcnMgYnkgYSBzcGFjZSBpcyByZXBvcnRlZCBhc1xuICogZHJpZnQgb24gdGhlIHdob2xlIHRhc2sgZGVmaW5pdGlvbiwgc28gdGhpcyBpcyBzb3J0ZWQgYW5kIHJlbmRlcmVkIGV4YWN0bHkgYXMgYHNpZGVjYXJDb21tYW5kYCBpbiB0aGVcbiAqIGNvbm5lY3RvciBkb2VzIGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2lkZWNhckNvbW1hbmQoYWdlbnREaXJzOiBzdHJpbmdbXSk6IHN0cmluZ1tdIHtcbiAgY29uc3QgZGlycyA9IFsuLi5uZXcgU2V0KGFnZW50RGlycyldLnNvcnQoKTtcbiAgbGV0IHNjcmlwdCA9IGBta2RpciAtcCAke0ZBUkdBVEVfQUdFTlRTX0RJUn1gO1xuICBmb3IgKGNvbnN0IGQgb2YgZGlycykge1xuICAgIHNjcmlwdCArPSBgICYmIGNwIC1yICR7RkFSR0FURV9JTUFHRV9BR0VOVFNfRElSfS8ke2R9ICR7RkFSR0FURV9BR0VOVFNfRElSfS8ke2R9YDtcbiAgfVxuICByZXR1cm4gWydzaCcsICctYycsIHNjcmlwdF07XG59XG5cbi8qKlxuICogVGhlIHJlc291cmNlIGF0dHJpYnV0ZXMgZXZlcnkgc3BhbiwgbWV0cmljIGFuZCBsb2cgZnJvbSBhbiBpbnN0cnVtZW50ZWQgdGFzayBjYXJyaWVzLiBgc2VydmljZS5uYW1lYCBpc1xuICogc2V0IHNlcGFyYXRlbHksIHRocm91Z2ggYE9URUxfU0VSVklDRV9OQU1FYC5cbiAqXG4gKiBUaGUgcmVnaW9uIG1heSBiZSBhbiB1bnJlc29sdmVkIHRva2VuIG9uIGFuIGVudmlyb25tZW50LWFnbm9zdGljIHN0YWNrLCB3aGljaCBpcyBmaW5lIGhlcmUgYW5kIHVubGlrZVxuICogdGhlIExhbWJkYSBsYXllciBsb29rdXA6IHRoaXMgdmFsdWUgaXMgYW4gZW52aXJvbm1lbnQgdmFyaWFibGUsIHNvIHRoZSB0b2tlbiByZXNvbHZlcyB0byBhIGBSZWZgIHRvXG4gKiBgQVdTOjpSZWdpb25gIGFuZCBDbG91ZEZvcm1hdGlvbiBmaWxscyBpbiB0aGUgcmVhbCByZWdpb24gYXQgZGVwbG95IHRpbWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmYXJnYXRlUmVzb3VyY2VBdHRyaWJ1dGVzKHJlZ2lvbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgYXR0cnMgPSAnY2xvdWQucHJvdmlkZXI9YXdzLGNsb3VkLnBsYXRmb3JtPWF3c19lY3MnO1xuICByZXR1cm4gcmVnaW9uID8gYCR7YXR0cnN9LGNsb3VkLnJlZ2lvbj0ke3JlZ2lvbn1gIDogYXR0cnM7XG59XG5cbi8qKiBXaGVyZSBhbiBpbnN0cnVtZW50ZWQgY29udGFpbmVyIGV4cG9ydHMgdG8sIGFuZCBvdmVyIHdoaWNoIHRyYW5zcG9ydC4gQWx3YXlzIGRlY2lkZWQgYXMgYSBwYWlyLiAqL1xuZXhwb3J0IGludGVyZmFjZSBGYXJnYXRlRXhwb3J0VGFyZ2V0IHtcbiAgLyoqIGBzY2hlbWU6Ly9ob3N0OnBvcnRgLiAqL1xuICByZWFkb25seSBlbmRwb2ludDogc3RyaW5nO1xuICAvKiogYGdycGNgIG9yIGBodHRwL3Byb3RvYnVmYC4gKi9cbiAgcmVhZG9ubHkgcHJvdG9jb2w6IHN0cmluZztcbn1cblxuLyoqXG4gKiBUdXJucyBhIGRlc3RpbmF0aW9uJ3MgT1RMUC9nUlBDIHRhcmdldCAoYGhvc3Q6cG9ydGApIGludG8gdGhlIFVSTCB0aGUgT3BlblRlbGVtZXRyeSBTREsgZW52IGFjY2VwdHMsXG4gKiB0YWtpbmcgdGhlIHNjaGVtZSBmcm9tIHRoZSBkZXN0aW5hdGlvbidzIFRMUyBzZXR0aW5nLiBBIHZhbHVlIHRoYXQgaXMgYWxyZWFkeSBhIFVSTCBwYXNzZXMgdGhyb3VnaC5cbiAqL1xuZnVuY3Rpb24gZ3JwY0VuZHBvaW50VVJMKGVuZHBvaW50OiBzdHJpbmcsIGluc2VjdXJlPzogYm9vbGVhbik6IHN0cmluZyB7XG4gIGlmIChlbmRwb2ludCA9PT0gJycpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cbiAgaWYgKGVuZHBvaW50LmluY2x1ZGVzKCc6Ly8nKSkge1xuICAgIHJldHVybiBlbmRwb2ludDtcbiAgfVxuICByZXR1cm4gYCR7aW5zZWN1cmUgPT09IHRydWUgPyAnaHR0cCcgOiAnaHR0cHMnfTovLyR7ZW5kcG9pbnR9YDtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyB0aGUgZW5kcG9pbnQgYW5kIHByb3RvY29sIGZvciBvbmUgcmVjaXBlIGFnYWluc3Qgb25lIGRlc3RpbmF0aW9uLlxuICpcbiAqIFBvcnQgb2YgYGV4cG9ydFRhcmdldEZvcmAuIEEgRmFyZ2F0ZSB0YXNrIGhhcyBubyBub2RlLWxvY2FsIGNvbGxlY3RvciDigJQgdW5saWtlIExhbWJkYSwgd2hlcmUgdGhlIFNES1xuICogZXhwb3J0cyB0byBhIGNvbGxlY3RvciBpbiB0aGUgc2FtZSBzYW5kYm94IOKAlCBzbyB0aGUgYWdlbnQgZXhwb3J0cyBPVExQIHN0cmFpZ2h0IHRvIHRoZSBkZXN0aW5hdGlvbiwgYW5kXG4gKiB3aGljaCB0cmFuc3BvcnQgaXQgY2FuIHVzZSBpcyBhIHByb3BlcnR5IG9mIHRoZSBhZ2VudCBhcyBtdWNoIGFzIG9mIHRoZSBkZXN0aW5hdGlvbi5cbiAqXG4gKiBFYWNoIGFnZW50J3MgUFJFRkVSUkVEIHRyYW5zcG9ydCBpcyB0YWtlbiB3aGVuIHRoZSBkZXN0aW5hdGlvbiBvZmZlcnMgaXQuIFdoZW4gaXQgZG9lcyBub3QsIGFuIGFnZW50XG4gKiB3aG9zZSBjb21tdW5pdHkgU0RLIHBpbnMgdGhlIHByb3RvY29sIChwaHAsIHJ1YnkpIGNhbm5vdCBiZSBzd2l0Y2hlZCBhbmQgdGhyb3dzOyBldmVyeSBvdGhlciBhZ2VudFxuICogaG9ub3VycyBgT1RFTF9FWFBPUlRFUl9PVExQX1BST1RPQ09MYCBhbmQgZmFsbHMgYmFjayB0byB3aGljaGV2ZXIgdHJhbnNwb3J0IGV4aXN0cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4cG9ydFRhcmdldEZvcihyZWNpcGU6IEZhcmdhdGVSZWNpcGUsIGRlc3Q6IE9kaWdvc0Rlc3RpbmF0aW9uKTogRmFyZ2F0ZUV4cG9ydFRhcmdldCB7XG4gIGNvbnN0IGdycGNVUkwgPSBncnBjRW5kcG9pbnRVUkwoZGVzdC5lbmRwb2ludCA/PyAnJywgZGVzdC5pbnNlY3VyZSk7XG4gIGNvbnN0IGh0dHBVUkwgPSBkZXN0Lmh0dHBFbmRwb2ludCA/PyAnJztcblxuICBpZiAocmVjaXBlLm90bHBQcm90b2NvbCA9PT0gT1RMUF9QUk9UT0NPTF9IVFRQICYmIGh0dHBVUkwgIT09ICcnKSB7XG4gICAgcmV0dXJuIHsgZW5kcG9pbnQ6IGh0dHBVUkwsIHByb3RvY29sOiBPVExQX1BST1RPQ09MX0hUVFAgfTtcbiAgfVxuICBpZiAocmVjaXBlLm90bHBQcm90b2NvbCA9PT0gT1RMUF9QUk9UT0NPTF9HUlBDICYmIGdycGNVUkwgIT09ICcnKSB7XG4gICAgcmV0dXJuIHsgZW5kcG9pbnQ6IGdycGNVUkwsIHByb3RvY29sOiBPVExQX1BST1RPQ09MX0dSUEMgfTtcbiAgfVxuICBpZiAocmVjaXBlLnByb3RvY29sRml4ZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgT2RpZ29zOiB0aGUgJHtyZWNpcGUubGFuZ3VhZ2V9IGFnZW50IGV4cG9ydHMgT1RMUCBvdmVyICR7cmVjaXBlLm90bHBQcm90b2NvbH0gb25seSDigJQgaXRzIGNvbW11bml0eSBgICtcbiAgICAgICAgJ1NESyBjYW5ub3QgYmUgc3dpdGNoZWQgdG8gdGhlIG90aGVyIHRyYW5zcG9ydCDigJQgYnV0IHRoZSBkZXN0aW5hdGlvbiBjb25maWd1cmVzIG5vICcgK1xuICAgICAgICBgJHtyZWNpcGUub3RscFByb3RvY29sID09PSBPVExQX1BST1RPQ09MX0hUVFAgPyAnYGh0dHBFbmRwb2ludGAnIDogJ2BlbmRwb2ludGAnfS4gYCArXG4gICAgICAgICdDb25maWd1cmUgb25lLCBvciBsZWF2ZSB0aGlzIGNvbnRhaW5lciB1bmluc3RydW1lbnRlZC4nLFxuICAgICk7XG4gIH1cbiAgaWYgKGh0dHBVUkwgIT09ICcnKSB7XG4gICAgcmV0dXJuIHsgZW5kcG9pbnQ6IGh0dHBVUkwsIHByb3RvY29sOiBPVExQX1BST1RPQ09MX0hUVFAgfTtcbiAgfVxuICBpZiAoZ3JwY1VSTCAhPT0gJycpIHtcbiAgICByZXR1cm4geyBlbmRwb2ludDogZ3JwY1VSTCwgcHJvdG9jb2w6IE9UTFBfUFJPVE9DT0xfR1JQQyB9O1xuICB9XG4gIHRocm93IG5ldyBFcnJvcihcbiAgICAnT2RpZ29zIGRlc3RpbmF0aW9uIGhhcyBuZWl0aGVyIGBlbmRwb2ludGAgKE9UTFAvZ1JQQykgbm9yIGBodHRwRW5kcG9pbnRgIChPVExQL0hUVFApLCBzbyBhbiAnICtcbiAgICAgICdpbnN0cnVtZW50ZWQgRmFyZ2F0ZSB0YXNrIHdvdWxkIGhhdmUgbm93aGVyZSB0byBleHBvcnQuIFVubGlrZSBMYW1iZGEsIGEgRmFyZ2F0ZSB0YXNrIGhhcyBubyAnICtcbiAgICAgICdpbi1zYW5kYm94IGNvbGxlY3RvciB0byBidWZmZXIgZm9yIGl0IOKAlCB0aGUgYWdlbnQgZXhwb3J0cyB0byB0aGlzIGRlc3RpbmF0aW9uIGRpcmVjdGx5LicsXG4gICk7XG59XG5cbi8qKiBUaGUgcG9ydCBvZiBhIGBzY2hlbWU6Ly9ob3N0OnBvcnRbL3BhdGhdYCBlbmRwb2ludCwgb3IgXCJcIiB3aGVuIGl0IG5hbWVzIG5vbmUuICovXG5mdW5jdGlvbiBlbmRwb2ludFBvcnQoZW5kcG9pbnQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIGxldCByZXN0ID0gZW5kcG9pbnQ7XG4gIGNvbnN0IHNjaGVtZSA9IHJlc3QuaW5kZXhPZignOi8vJyk7XG4gIGlmIChzY2hlbWUgPj0gMCkge1xuICAgIHJlc3QgPSByZXN0LnNsaWNlKHNjaGVtZSArIDMpO1xuICB9XG4gIGNvbnN0IHBhdGhTdGFydCA9IHJlc3Quc2VhcmNoKC9bLz9dLyk7XG4gIGlmIChwYXRoU3RhcnQgPj0gMCkge1xuICAgIHJlc3QgPSByZXN0LnNsaWNlKDAsIHBhdGhTdGFydCk7XG4gIH1cbiAgY29uc3QgY29sb24gPSByZXN0Lmxhc3RJbmRleE9mKCc6Jyk7XG4gIHJldHVybiBjb2xvbiA8IDAgPyAnJyA6IHJlc3Quc2xpY2UoY29sb24gKyAxKTtcbn1cblxuLyoqXG4gKiBBIHdhcm5pbmcgd2hlbiBhbiBlbmRwb2ludCdzIHBvcnQgaXMgdGhlIHdlbGwta25vd24gcG9ydCBvZiB0aGUgT1RIRVIgT1RMUCBwcm90b2NvbCwgb3IgXCJcIiB3aGVuIHRoZVxuICogcGFpcmluZyBsb29rcyByaWdodCDigJQgaW5jbHVkaW5nIGEgbm9uLXN0YW5kYXJkIHBvcnQsIHdoaWNoIGNhbm5vdCBiZSBqdWRnZWQuXG4gKlxuICogV29ydGggYSBzeW50aC10aW1lIHdhcm5pbmcgYmVjYXVzZSB0aGUgcnVudGltZSBzeW1wdG9tIGlzIGEgY29ubmVjdGlvbiByZXNldCBtaWQtZXhwb3J0LCB3aGljaCBwb2ludHNcbiAqIG5vd2hlcmUgbmVhciB0aGUgY2F1c2U6IGFuIEhUVFAgcmVxdWVzdCBhZ2FpbnN0IGFuIEhUVFAvMiBnUlBDIGxpc3RlbmVyLCBvciB0aGUgcmV2ZXJzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvcnRQcm90b2NvbE1pc21hdGNoKGVuZHBvaW50OiBzdHJpbmcsIHByb3RvY29sOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBwb3J0ID0gZW5kcG9pbnRQb3J0KGVuZHBvaW50KTtcbiAgaWYgKHByb3RvY29sID09PSBPVExQX1BST1RPQ09MX0hUVFAgJiYgcG9ydCA9PT0gT1RMUF9ERUZBVUxUX0dSUENfUE9SVCkge1xuICAgIHJldHVybiAoXG4gICAgICBgZW5kcG9pbnQgJHtlbmRwb2ludH0gaXMgb24gJHtPVExQX0RFRkFVTFRfR1JQQ19QT1JUfSwgdGhlIHN0YW5kYXJkIE9UTFAvZ1JQQyBwb3J0LCBidXQgdGhpcyBhZ2VudCBgICtcbiAgICAgIGBleHBvcnRzIG92ZXIgJHtPVExQX1BST1RPQ09MX0hUVFB9OyBleHBvcnRzIHdpbGwgZmFpbCBhcyBhIGNvbm5lY3Rpb24gcmVzZXQuIFBvaW50IGl0IGF0IHRoZSBgICtcbiAgICAgIGBPVExQL0hUVFAgcG9ydCAoJHtPVExQX0RFRkFVTFRfSFRUUF9QT1JUfSkuYFxuICAgICk7XG4gIH1cbiAgaWYgKHByb3RvY29sID09PSBPVExQX1BST1RPQ09MX0dSUEMgJiYgcG9ydCA9PT0gT1RMUF9ERUZBVUxUX0hUVFBfUE9SVCkge1xuICAgIHJldHVybiAoXG4gICAgICBgZW5kcG9pbnQgJHtlbmRwb2ludH0gaXMgb24gJHtPVExQX0RFRkFVTFRfSFRUUF9QT1JUfSwgdGhlIHN0YW5kYXJkIE9UTFAvSFRUUCBwb3J0LCBidXQgdGhpcyBhZ2VudCBgICtcbiAgICAgIGBleHBvcnRzIG92ZXIgZ1JQQzsgZXhwb3J0cyB3aWxsIGZhaWwuIFBvaW50IGl0IGF0IHRoZSBPVExQL2dSUEMgcG9ydCAoJHtPVExQX0RFRkFVTFRfR1JQQ19QT1JUfSkuYFxuICAgICk7XG4gIH1cbiAgcmV0dXJuICcnO1xufVxuIl19
@@ -0,0 +1,218 @@
1
+ import * as ecs from 'aws-cdk-lib/aws-ecs';
2
+ import { Construct } from 'constructs';
3
+ import { OdigosDestination, OdigosFargateLanguage } from './types';
4
+ /**
5
+ * Options shared by every container this construct instruments.
6
+ */
7
+ export interface OdigosFargateInstrumentationOptions {
8
+ /**
9
+ * Where the instrumented containers export telemetry to.
10
+ *
11
+ * Unlike Lambda, BOTH transports may be set and often should be: a Fargate task has no collector of its
12
+ * own, so each language's agent exports to this destination itself and takes the transport it prefers.
13
+ * php and ruby can only speak OTLP/HTTP at all.
14
+ */
15
+ readonly destination: OdigosDestination;
16
+ /**
17
+ * The agents bundle the staging container copies the language agents out of.
18
+ *
19
+ * Defaults to the multi-arch image this package's release published, at that release's immutable tag.
20
+ * Override it to mirror the image into a registry your tasks can reach — the image is pulled by YOUR
21
+ * task's execution role at every task start, so a task in a private subnet with no NAT and no
22
+ * interface endpoint cannot pull the default.
23
+ *
24
+ * A mirror must be the same bundle: the activation environment set below names exact paths inside it.
25
+ *
26
+ * @default - the released `registry.odigos.io/odigos-fargate-agents` image for this package version
27
+ */
28
+ readonly agentsImage?: string;
29
+ /**
30
+ * Raise agent verbosity (`OTEL_LOG_LEVEL=debug`) on every instrumented container.
31
+ *
32
+ * Useful while wiring up a destination, expensive to leave on — and it is compared: the connector
33
+ * expects the variable ABSENT unless debug telemetry is enabled for the connector too, so leaving this
34
+ * on can itself be reported as drift.
35
+ *
36
+ * @default false
37
+ */
38
+ readonly debug?: boolean;
39
+ }
40
+ /**
41
+ * One container to instrument.
42
+ */
43
+ export interface OdigosFargateTarget {
44
+ /**
45
+ * The application container. Its task definition is taken from it, so the staging container, the shared
46
+ * volume and the startup dependency are added to the right one automatically.
47
+ */
48
+ readonly container: ecs.ContainerDefinition;
49
+ /**
50
+ * The language whose agent to stage and activate.
51
+ *
52
+ * Stated rather than detected — a container declares an image, not a runtime, and resolving a language
53
+ * from an image means pulling it.
54
+ */
55
+ readonly language: OdigosFargateLanguage;
56
+ /**
57
+ * `OTEL_SERVICE_NAME` for this container.
58
+ *
59
+ * THIS MUST MATCH THE WORKLOAD'S NAME IN ODIGOS, which for a Fargate workload is the ECS SERVICE name —
60
+ * not the task definition family and not the container name. A different value is reported as
61
+ * instrumentation drift rather than treated as a naming preference.
62
+ *
63
+ * Pass `service` instead to read it off the service, or set this when the service is defined elsewhere
64
+ * (a different stack, Terraform, the console). One of the two is required.
65
+ *
66
+ * @default - taken from `service`
67
+ */
68
+ readonly serviceName?: string;
69
+ /**
70
+ * The ECS service that runs this task definition, used only to read its name.
71
+ *
72
+ * Its physical name has to be one your stack SET, not one CloudFormation generates: a generated name is
73
+ * a `Ref` to the service, and a service's own task definition referencing it is a dependency cycle
74
+ * CloudFormation rejects at deploy time. A generated name throws at synth pointing at `serviceName`.
75
+ *
76
+ * @default - `serviceName` must be given instead
77
+ */
78
+ readonly service?: ecs.BaseService;
79
+ /**
80
+ * The application's runtime version as `major.minor` — for example `"8.3"`.
81
+ *
82
+ * Required for php and ruby, whose agents are laid down per runtime version in the bundle, and the
83
+ * version selects the path their activation variables point at. Ignored by every other language.
84
+ *
85
+ * @default - none; required for php and ruby
86
+ */
87
+ readonly runtimeVersion?: string;
88
+ /**
89
+ * The value this container already needs in its loader variable (`JAVA_TOOL_OPTIONS`, `NODE_OPTIONS` or
90
+ * `PYTHONPATH`), which the Odigos fragment is joined to rather than replacing.
91
+ *
92
+ * Only needed as an OVERRIDE. The construct reads the value the container was created with and appends
93
+ * to it, so a container that sets its own `JAVA_TOOL_OPTIONS` in `addContainer` keeps it. Pass this when
94
+ * the value is not visible at synth — set by an `environmentFiles` entry, injected by the image's own
95
+ * `ENV`, or supplied through `secrets`.
96
+ *
97
+ * @default - read from the container's own environment
98
+ */
99
+ readonly existingLoaderValue?: string;
100
+ }
101
+ /**
102
+ * Props for {@link OdigosFargateInstrumentation}.
103
+ */
104
+ export interface OdigosFargateInstrumentationProps extends OdigosFargateInstrumentationOptions {
105
+ /**
106
+ * Containers to instrument on construction. More can be added with `instrument()`.
107
+ *
108
+ * @default - none
109
+ */
110
+ readonly targets?: OdigosFargateTarget[];
111
+ }
112
+ /**
113
+ * Instruments ECS Fargate containers with the Odigos OpenTelemetry agents.
114
+ *
115
+ * ```ts
116
+ * const odigos = new OdigosFargateInstrumentation(this, 'Odigos', {
117
+ * destination: { httpEndpoint: 'https://otlp.example.com:4318' },
118
+ * });
119
+ * odigos.instrument({
120
+ * container: apiContainer,
121
+ * language: OdigosFargateLanguage.JAVA,
122
+ * service: apiService,
123
+ * });
124
+ * ```
125
+ *
126
+ * ## What it does to the task definition
127
+ *
128
+ * Four moves, which are one mechanism and only work together — the ECS adaptation of the Odikos
129
+ * init-container mount method:
130
+ *
131
+ * 1. a bare-name task volume (`odigos-agent`), which on Fargate is an ephemeral-storage bind mount
132
+ * scoped to the task;
133
+ * 2. a NON-ESSENTIAL `odigos-agent` container that copies the language agents out of the agents bundle
134
+ * into that volume and exits 0;
135
+ * 3. the volume mounted read-only at `/var/odigos` in each instrumented container, which depends on the
136
+ * staging container with condition `SUCCESS` — only valid against a non-essential container, which is
137
+ * why (2) is non-essential;
138
+ * 4. the language's activation environment, the OTLP export environment, and the `ODIGOS_IAC` marker on
139
+ * each instrumented container.
140
+ *
141
+ * There is ONE staging container per task definition however many languages the task holds; its command
142
+ * is the union of every instrumented container's agent directories, and it is built lazily so containers
143
+ * instrumented later are included.
144
+ *
145
+ * ## Where the telemetry goes
146
+ *
147
+ * Straight to your destination, from inside the application process. This is the substantive difference
148
+ * from Lambda: there is no collector in the task to hand a batch to, so a slow or unreachable destination
149
+ * is felt by the application's own exporter rather than absorbed after a response has been returned.
150
+ *
151
+ * ## What it deliberately does NOT do
152
+ *
153
+ * There is no aspect that sweeps a scope, as there is for Lambda. An aspect there works because a
154
+ * function DECLARES its runtime; a container declares an image, and a language guessed from an image name
155
+ * would silently mis-instrument the ones it got wrong — staging a Java agent into a Python container
156
+ * leaves it uninstrumented, and a `JAVA_TOOL_OPTIONS` on a JVM-less image is simply ignored, so nothing
157
+ * fails loudly enough to notice.
158
+ *
159
+ * ## Do not also instrument these services with the connector
160
+ *
161
+ * The connector instruments live services by registering a new task-definition revision and updating the
162
+ * service to it, reconciling to its own desired state on every pass. A service instrumented here and also
163
+ * enabled as a connector source ends up owned by both: each `cdk deploy` reasserts the stack's
164
+ * definition, each reconcile reasserts the connector's, and every round trip registers a revision and
165
+ * rolls the service. Choose one per service.
166
+ */
167
+ export declare class OdigosFargateInstrumentation extends Construct {
168
+ private readonly options;
169
+ private readonly agentsImage;
170
+ private readonly taskDefinitions;
171
+ private readonly instrumented;
172
+ constructor(scope: Construct, id: string, props: OdigosFargateInstrumentationProps);
173
+ /**
174
+ * Instruments one container. Idempotent — instrumenting the same container twice is a no-op rather than
175
+ * a doubled loader value.
176
+ */
177
+ instrument(target: OdigosFargateTarget): void;
178
+ /** Instruments every target in the list. */
179
+ instrumentAll(targets: OdigosFargateTarget[]): void;
180
+ /**
181
+ * The task definition's staging container and volume, created once and shared by every container in it.
182
+ *
183
+ * The command is a lazy list rather than a literal because the union it renders is not known until
184
+ * synthesis: a task definition holding a Java and a Python application is instrumented by two
185
+ * `instrument()` calls, and the single staging container has to stage both. The connector compares this
186
+ * command against exactly that union, so a stale one is reported as drift on the whole task definition
187
+ * and leaves one of the containers with no agent on disk.
188
+ */
189
+ private taskDefinitionState;
190
+ /**
191
+ * `OTEL_SERVICE_NAME` for a target, and the one value a caller cannot be allowed to leave to a default.
192
+ *
193
+ * The connector compares it against the workload's name in Odigos, which is the ECS SERVICE name, so
194
+ * guessing — the task definition family, the container name, the construct id — would produce a stack
195
+ * that deploys cleanly and then reports as drifted on a component nothing in the stack makes visible.
196
+ *
197
+ * Read from the L1, not from `service.serviceName`: the L2 property is a token that resolves to a `Ref`
198
+ * to the service even when the stack set the name explicitly, and a `Ref` here is worse than useless —
199
+ * the task definition would reference the service that references it, which CloudFormation rejects as a
200
+ * dependency cycle at deploy time.
201
+ */
202
+ private resolveServiceName;
203
+ /**
204
+ * Checks the task definition can carry the staged-agent method at all, and warns about the things that
205
+ * are legal but almost certainly a mistake.
206
+ */
207
+ private checkTaskDefinition;
208
+ /**
209
+ * The environment applied to one instrumented container.
210
+ *
211
+ * Mirrors `instrumentContainer` in the connector, including the ORDER of decisions: the agent's own
212
+ * activation variables first, then identity, then export, then the marker. Every variable here has a
213
+ * counterpart in the connector's `containerDiff`, which is what a customer's conformance report is
214
+ * built from — so one that is absent, or spelled differently, is reported as a named broken component
215
+ * rather than passing quietly.
216
+ */
217
+ private environmentFor;
218
+ }