@raindancers/raindancers-crew 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +10552 -0
- package/.kiro/specs/private-brain-construct-changes/design.md +147 -0
- package/.kiro/specs/private-brain-construct-changes/requirements.md +123 -0
- package/.kiro/specs/private-brain-construct-changes/tasks.md +119 -0
- package/API.md +1821 -0
- package/LICENSE +202 -0
- package/README.md +253 -0
- package/lib/crew-backup-bucket.d.ts +62 -0
- package/lib/crew-backup-bucket.js +108 -0
- package/lib/fargate-crew-base.d.ts +68 -0
- package/lib/fargate-crew-base.js +102 -0
- package/lib/fargate-crew.d.ts +89 -0
- package/lib/fargate-crew.js +200 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +22 -0
- package/lib/remote-crew-instance-props.d.ts +287 -0
- package/lib/remote-crew-instance-props.js +15 -0
- package/lib/remote-crew-instance.d.ts +35 -0
- package/lib/remote-crew-instance.js +309 -0
- package/package.json +138 -0
- package/src/assets/backup.sh +57 -0
- package/src/assets/bootstrap.sh +339 -0
- package/src/assets/restore-from-s3.sh +51 -0
- package/src/crew-backup-bucket.ts +107 -0
- package/src/fargate-crew-base.ts +109 -0
- package/src/fargate-crew.ts +248 -0
- package/src/index.ts +5 -0
- package/src/remote-crew-instance-props.ts +316 -0
- package/src/remote-crew-instance.ts +395 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
|
2
|
+
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
3
|
+
import * as s3 from 'aws-cdk-lib/aws-s3';
|
|
4
|
+
/**
|
|
5
|
+
* CPU architecture for the KiroCrew EC2 instance. Selects the matching
|
|
6
|
+
* Amazon Linux 2023 AMI and the pinned Node.js / kiro-cli download.
|
|
7
|
+
*/
|
|
8
|
+
export declare enum CrewArchitecture {
|
|
9
|
+
/** 64-bit ARM (Graviton). The upstream default. */
|
|
10
|
+
ARM64 = "arm64",
|
|
11
|
+
/** 64-bit x86. */
|
|
12
|
+
X86_64 = "x86_64"
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* How the KiroCrew source is delivered to the instance at first boot.
|
|
16
|
+
*
|
|
17
|
+
* Exactly one mode is active. When {@link sourceBucket} is set the instance
|
|
18
|
+
* downloads a source tarball from S3 (and is granted read on just that one
|
|
19
|
+
* object); otherwise it shallow-clones {@link kirocrewRef} from
|
|
20
|
+
* {@link kirocrewRepo}.
|
|
21
|
+
*/
|
|
22
|
+
export interface CrewSource {
|
|
23
|
+
/**
|
|
24
|
+
* S3 bucket holding the source tarball (`kirocrew-src.tar.gz`). When set,
|
|
25
|
+
* the instance role is granted `s3:GetObject` on this object ONLY. Leave
|
|
26
|
+
* unset to clone from git instead.
|
|
27
|
+
*
|
|
28
|
+
* @default - clone from git (see kirocrewRepo / kirocrewRef)
|
|
29
|
+
*/
|
|
30
|
+
readonly sourceBucket?: string;
|
|
31
|
+
/**
|
|
32
|
+
* S3 key of the source tarball within {@link sourceBucket}. Required when
|
|
33
|
+
* `sourceBucket` is set; ignored otherwise.
|
|
34
|
+
*
|
|
35
|
+
* @default - none
|
|
36
|
+
*/
|
|
37
|
+
readonly sourceKey?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Git repository to clone when no S3 source is configured.
|
|
40
|
+
*
|
|
41
|
+
* @default 'https://github.com/kirodotdev/KiroCrew.git'
|
|
42
|
+
*/
|
|
43
|
+
readonly kirocrewRepo?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Git ref (branch or tag) to install when cloning.
|
|
46
|
+
*
|
|
47
|
+
* Pin this to a released tag for reproducible, version-controlled deploys —
|
|
48
|
+
* the upstream launcher defaults to `main`, which drifts. This construct
|
|
49
|
+
* defaults to `main` only to match upstream; SET IT to a tag in production.
|
|
50
|
+
*
|
|
51
|
+
* @default 'main'
|
|
52
|
+
*/
|
|
53
|
+
readonly kirocrewRef?: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Exposes the gateway's webhook port to ONE source security group.
|
|
57
|
+
*
|
|
58
|
+
* There is deliberately no CIDR form: the brain box is never internet-
|
|
59
|
+
* reachable by contract. The named source SG (e.g. an ingest Lambda's SG, or a
|
|
60
|
+
* reverse proxy that fronts the loopback gateway) is the only peer allowed to
|
|
61
|
+
* reach the port.
|
|
62
|
+
*
|
|
63
|
+
* NOTE: the KiroCrew gateway binds loopback (`127.0.0.1`) only — it exposes no
|
|
64
|
+
* routable listener. This rule opens the security group so a consumer-owned
|
|
65
|
+
* reverse proxy / tunnel on the box can be reached from the source SG; actually
|
|
66
|
+
* serving the webhook on a routable interface is the consumer's concern (see
|
|
67
|
+
* README "Private dual-stack brain" and the webhook Decisions-for-review).
|
|
68
|
+
*/
|
|
69
|
+
export interface WebhookIngress {
|
|
70
|
+
/**
|
|
71
|
+
* Imported security group allowed to reach the webhook port. Passed as an
|
|
72
|
+
* `ISecurityGroup` (imported) — this construct never creates it.
|
|
73
|
+
*/
|
|
74
|
+
readonly source: ec2.ISecurityGroup;
|
|
75
|
+
/**
|
|
76
|
+
* TCP port the ingress rule opens. Defaults to the dashboard/gateway port so
|
|
77
|
+
* a reverse proxy fronting the loopback gateway is reachable; override to
|
|
78
|
+
* target a consumer proxy on a different port.
|
|
79
|
+
*
|
|
80
|
+
* @default - the resolved dashboardPort (5476)
|
|
81
|
+
*/
|
|
82
|
+
readonly port?: number;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Always-on runtime settings for the hosted crew, threaded into the crew
|
|
86
|
+
* `config.json` at boot. All fields are optional and default to the current
|
|
87
|
+
* gateway behaviour; omitting {@link RemoteCrewInstanceProps.crewRuntime}
|
|
88
|
+
* entirely reproduces today's `kirocrew setup --agent-only` + `kirocrew
|
|
89
|
+
* gateway` exactly.
|
|
90
|
+
*
|
|
91
|
+
* Verified against KiroCrew v0.6.0: autopilot maps to `agent.approval_mode`,
|
|
92
|
+
* idle-close maps to `session.timeout_secs`, and the conductor roster ships
|
|
93
|
+
* with `setup --agent-only` (custom members are source-delivered JSON under
|
|
94
|
+
* `~/.kiro/agents/`).
|
|
95
|
+
*/
|
|
96
|
+
export interface CrewRuntime {
|
|
97
|
+
/**
|
|
98
|
+
* Enable Autopilot: the hosted crew auto-approves tool calls that pass its
|
|
99
|
+
* security checks (deny rules and sensitive-path blocks still apply). Sets
|
|
100
|
+
* `agent.approval_mode` to `"auto"` in config.json.
|
|
101
|
+
*
|
|
102
|
+
* @default false (interactive; gateway default)
|
|
103
|
+
*/
|
|
104
|
+
readonly autopilot?: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Keep the 24/7 brain session alive between events by disabling the idle
|
|
107
|
+
* session sweep. Sets `session.timeout_secs` to `0` (documented: "0 disables
|
|
108
|
+
* the idle sweep").
|
|
109
|
+
*
|
|
110
|
+
* @default false (default 3600s idle timeout applies)
|
|
111
|
+
*/
|
|
112
|
+
readonly disableIdleClose?: boolean;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Properties for {@link RemoteCrewInstance}.
|
|
116
|
+
*/
|
|
117
|
+
export interface RemoteCrewInstanceProps {
|
|
118
|
+
/**
|
|
119
|
+
* VPC to launch the instance into.
|
|
120
|
+
*/
|
|
121
|
+
readonly vpc: ec2.IVpc;
|
|
122
|
+
/**
|
|
123
|
+
* ARN of an IAM permissions boundary applied to the instance role.
|
|
124
|
+
*
|
|
125
|
+
* The instance runs a prompt-injectable agent that executes arbitrary
|
|
126
|
+
* tools, so its role MUST carry a boundary that caps blast radius. This is
|
|
127
|
+
* required, not optional.
|
|
128
|
+
*/
|
|
129
|
+
readonly permissionsBoundaryArn: string;
|
|
130
|
+
/**
|
|
131
|
+
* Subnet selection for the instance. A public (IGW-routed) subnet needs a
|
|
132
|
+
* public IP for egress; a private (NAT-routed) subnet does not — see
|
|
133
|
+
* {@link associatePublicIp}.
|
|
134
|
+
*
|
|
135
|
+
* @default - one public subnet in the VPC
|
|
136
|
+
*/
|
|
137
|
+
readonly vpcSubnets?: ec2.SubnetSelection;
|
|
138
|
+
/**
|
|
139
|
+
* EC2 instance type.
|
|
140
|
+
*
|
|
141
|
+
* @default - m7g.2xlarge (arm64) / m7i.2xlarge (x86_64), matching the
|
|
142
|
+
* upstream "Development" size tier
|
|
143
|
+
*/
|
|
144
|
+
readonly instanceType?: ec2.InstanceType;
|
|
145
|
+
/**
|
|
146
|
+
* CPU architecture. Must match {@link instanceType} when that is set.
|
|
147
|
+
*
|
|
148
|
+
* @default CrewArchitecture.ARM64
|
|
149
|
+
*/
|
|
150
|
+
readonly architecture?: CrewArchitecture;
|
|
151
|
+
/**
|
|
152
|
+
* gp3 root volume size in GiB (20–1000). The volume is always encrypted.
|
|
153
|
+
*
|
|
154
|
+
* @default 60
|
|
155
|
+
*/
|
|
156
|
+
readonly volumeSizeGb?: number;
|
|
157
|
+
/**
|
|
158
|
+
* Attach a public IP to the instance ENI. Required for egress on IGW-only
|
|
159
|
+
* subnets; leave off (false) for NAT-routed private subnets, where it is
|
|
160
|
+
* unused attack surface.
|
|
161
|
+
*
|
|
162
|
+
* @default true
|
|
163
|
+
*/
|
|
164
|
+
readonly associatePublicIp?: boolean;
|
|
165
|
+
/**
|
|
166
|
+
* Assign an IPv6 address to the instance's primary ENI and permit IPv6
|
|
167
|
+
* egress on the security group.
|
|
168
|
+
*
|
|
169
|
+
* Enables a dual-stack posture: combined with `associatePublicIp: false` and
|
|
170
|
+
* a private, IPv6-capable subnet, the instance egresses over IPv6 (via the
|
|
171
|
+
* VPC's Egress-Only Internet Gateway) with no public IPv4. CDK's
|
|
172
|
+
* `allowAllOutbound` renders IPv4 `0.0.0.0/0` egress only, so this also adds
|
|
173
|
+
* an explicit all-traffic IPv6 egress rule.
|
|
174
|
+
*
|
|
175
|
+
* This construct does NOT provision subnet IPv6 CIDRs, an Egress-Only
|
|
176
|
+
* Internet Gateway, or any route — those are the consumer VPC's
|
|
177
|
+
* responsibility. The selected subnet(s) MUST already carry IPv6 CIDRs.
|
|
178
|
+
*
|
|
179
|
+
* @default false
|
|
180
|
+
*/
|
|
181
|
+
readonly enableIpv6?: boolean;
|
|
182
|
+
/**
|
|
183
|
+
* Discovery tag value written as `kirocrew:instance`. Must match
|
|
184
|
+
* `[a-zA-Z0-9-]{1,51}`.
|
|
185
|
+
*
|
|
186
|
+
* @default 'kirocrew'
|
|
187
|
+
*/
|
|
188
|
+
readonly stackTag?: string;
|
|
189
|
+
/**
|
|
190
|
+
* TCP port the gateway serves the dashboard on (loopback only; reached via
|
|
191
|
+
* SSM port-forward). Recorded in the instance registry as the remote port.
|
|
192
|
+
*
|
|
193
|
+
* @default 5476
|
|
194
|
+
*/
|
|
195
|
+
readonly dashboardPort?: number;
|
|
196
|
+
/**
|
|
197
|
+
* Optional SSH ingress CIDR. When set (and no wider than /16), opens tcp/22
|
|
198
|
+
* from that CIDR as a fallback. Omit for SSM-only access (recommended).
|
|
199
|
+
*
|
|
200
|
+
* @default - no inbound; SSM-only
|
|
201
|
+
*/
|
|
202
|
+
readonly allowSshCidr?: string;
|
|
203
|
+
/**
|
|
204
|
+
* Open the gateway/webhook port to ONE source security group only (never a
|
|
205
|
+
* CIDR). Independent of {@link allowSshCidr} — both, either, or neither may
|
|
206
|
+
* be set; unset leaves the SG no-inbound (the default).
|
|
207
|
+
*
|
|
208
|
+
* @default - no webhook ingress
|
|
209
|
+
*/
|
|
210
|
+
readonly webhookIngress?: WebhookIngress;
|
|
211
|
+
/**
|
|
212
|
+
* Secrets Manager ARN of the Bearer token that authenticates the native
|
|
213
|
+
* webhook (`POST /api/hooks/agent`). At boot the instance fetches the secret
|
|
214
|
+
* and writes it as `hooks.webhook_token` in the crew `config.json` — the
|
|
215
|
+
* token is never baked into userData, env literals, or code. The instance
|
|
216
|
+
* role is granted `secretsmanager:GetSecretValue` on THIS ARN only.
|
|
217
|
+
*
|
|
218
|
+
* Required when {@link webhookIngress} is set: a reachable webhook with no
|
|
219
|
+
* auth is a defect, not a default, so synth fails if ingress is opened
|
|
220
|
+
* without a token.
|
|
221
|
+
*
|
|
222
|
+
* NOTE: the KiroCrew gateway binds loopback (`127.0.0.1`) only and exposes no
|
|
223
|
+
* routable webhook listener — see the webhook Decisions-for-review in the PR.
|
|
224
|
+
* This wires the AUTH (token-in-config); routable exposure of the loopback
|
|
225
|
+
* route is a consumer reverse-proxy / tunnel concern.
|
|
226
|
+
*
|
|
227
|
+
* @default - webhook auth not configured (loopback / SSM only)
|
|
228
|
+
*/
|
|
229
|
+
readonly webhookTokenSecretArn?: string;
|
|
230
|
+
/**
|
|
231
|
+
* Always-on runtime settings (Autopilot, no-idle-close) for the hosted crew,
|
|
232
|
+
* threaded into config.json at boot. Omit for the current gateway defaults.
|
|
233
|
+
*
|
|
234
|
+
* @default - current gateway behaviour (interactive, 3600s idle timeout)
|
|
235
|
+
*/
|
|
236
|
+
readonly crewRuntime?: CrewRuntime;
|
|
237
|
+
/**
|
|
238
|
+
* How the KiroCrew source reaches the instance (S3 tarball or git clone).
|
|
239
|
+
*
|
|
240
|
+
* @default - clone kirodotdev/KiroCrew@main
|
|
241
|
+
*/
|
|
242
|
+
readonly source?: CrewSource;
|
|
243
|
+
/**
|
|
244
|
+
* Minutes to wait for the gateway to become healthy before the stack fails
|
|
245
|
+
* and rolls back (cold boot + dnf + Node + vite build + pip).
|
|
246
|
+
*
|
|
247
|
+
* @default 25
|
|
248
|
+
*/
|
|
249
|
+
readonly bootstrapTimeoutMinutes?: number;
|
|
250
|
+
/**
|
|
251
|
+
* An S3 backup bucket to push crew snapshots to on a schedule. When set, the
|
|
252
|
+
* instance role is granted write, a systemd timer runs
|
|
253
|
+
* `kirocrew snapshot --purpose backup` and uploads the newest (redaction-
|
|
254
|
+
* scrubbed) bundle, and a `kirocrew-restore-from-s3` helper is installed for
|
|
255
|
+
* rebuilding a replacement instance. Omit to disable off-box backup.
|
|
256
|
+
*
|
|
257
|
+
* @default - no off-box backup
|
|
258
|
+
*/
|
|
259
|
+
readonly backupBucket?: ICrewBackupBucket;
|
|
260
|
+
/**
|
|
261
|
+
* systemd OnCalendar expression for the backup timer (see
|
|
262
|
+
* `man systemd.time`). Only used when {@link backupBucket} is set.
|
|
263
|
+
*
|
|
264
|
+
* @default 'daily'
|
|
265
|
+
*/
|
|
266
|
+
readonly backupSchedule?: string;
|
|
267
|
+
/**
|
|
268
|
+
* S3 key prefix under which snapshots are stored in the backup bucket.
|
|
269
|
+
* Only used when {@link backupBucket} is set. A trailing slash is added if
|
|
270
|
+
* absent.
|
|
271
|
+
*
|
|
272
|
+
* @default 'crew-snapshots/'
|
|
273
|
+
*/
|
|
274
|
+
readonly backupPrefix?: string;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* The subset of {@link CrewBackupBucket} the EC2/Fargate constructs need. Kept
|
|
278
|
+
* as an interface so a consumer can pass their own bucket wrapper.
|
|
279
|
+
*/
|
|
280
|
+
export interface ICrewBackupBucket {
|
|
281
|
+
/** The destination bucket name. */
|
|
282
|
+
readonly bucket: s3.IBucket;
|
|
283
|
+
/** Grant a principal write access to snapshots (bucket + KMS). */
|
|
284
|
+
grantWrite(grantee: iam.IGrantable): void;
|
|
285
|
+
/** Grant a principal read access to snapshots (bucket + KMS). */
|
|
286
|
+
grantRead(grantee: iam.IGrantable): void;
|
|
287
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CrewArchitecture = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* CPU architecture for the KiroCrew EC2 instance. Selects the matching
|
|
6
|
+
* Amazon Linux 2023 AMI and the pinned Node.js / kiro-cli download.
|
|
7
|
+
*/
|
|
8
|
+
var CrewArchitecture;
|
|
9
|
+
(function (CrewArchitecture) {
|
|
10
|
+
/** 64-bit ARM (Graviton). The upstream default. */
|
|
11
|
+
CrewArchitecture["ARM64"] = "arm64";
|
|
12
|
+
/** 64-bit x86. */
|
|
13
|
+
CrewArchitecture["X86_64"] = "x86_64";
|
|
14
|
+
})(CrewArchitecture || (exports.CrewArchitecture = CrewArchitecture = {}));
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVtb3RlLWNyZXctaW5zdGFuY2UtcHJvcHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcmVtb3RlLWNyZXctaW5zdGFuY2UtcHJvcHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBSUE7OztHQUdHO0FBQ0gsSUFBWSxnQkFLWDtBQUxELFdBQVksZ0JBQWdCO0lBQzFCLG1EQUFtRDtJQUNuRCxtQ0FBZSxDQUFBO0lBQ2Ysa0JBQWtCO0lBQ2xCLHFDQUFpQixDQUFBO0FBQ25CLENBQUMsRUFMVyxnQkFBZ0IsZ0NBQWhCLGdCQUFnQixRQUszQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGVjMiBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWMyJztcbmltcG9ydCAqIGFzIGlhbSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCAqIGFzIHMzIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zMyc7XG5cbi8qKlxuICogQ1BVIGFyY2hpdGVjdHVyZSBmb3IgdGhlIEtpcm9DcmV3IEVDMiBpbnN0YW5jZS4gU2VsZWN0cyB0aGUgbWF0Y2hpbmdcbiAqIEFtYXpvbiBMaW51eCAyMDIzIEFNSSBhbmQgdGhlIHBpbm5lZCBOb2RlLmpzIC8ga2lyby1jbGkgZG93bmxvYWQuXG4gKi9cbmV4cG9ydCBlbnVtIENyZXdBcmNoaXRlY3R1cmUge1xuICAvKiogNjQtYml0IEFSTSAoR3Jhdml0b24pLiBUaGUgdXBzdHJlYW0gZGVmYXVsdC4gKi9cbiAgQVJNNjQgPSAnYXJtNjQnLFxuICAvKiogNjQtYml0IHg4Ni4gKi9cbiAgWDg2XzY0ID0gJ3g4Nl82NCcsXG59XG5cbi8qKlxuICogSG93IHRoZSBLaXJvQ3JldyBzb3VyY2UgaXMgZGVsaXZlcmVkIHRvIHRoZSBpbnN0YW5jZSBhdCBmaXJzdCBib290LlxuICpcbiAqIEV4YWN0bHkgb25lIG1vZGUgaXMgYWN0aXZlLiBXaGVuIHtAbGluayBzb3VyY2VCdWNrZXR9IGlzIHNldCB0aGUgaW5zdGFuY2VcbiAqIGRvd25sb2FkcyBhIHNvdXJjZSB0YXJiYWxsIGZyb20gUzMgKGFuZCBpcyBncmFudGVkIHJlYWQgb24ganVzdCB0aGF0IG9uZVxuICogb2JqZWN0KTsgb3RoZXJ3aXNlIGl0IHNoYWxsb3ctY2xvbmVzIHtAbGluayBraXJvY3Jld1JlZn0gZnJvbVxuICoge0BsaW5rIGtpcm9jcmV3UmVwb30uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ3Jld1NvdXJjZSB7XG4gIC8qKlxuICAgKiBTMyBidWNrZXQgaG9sZGluZyB0aGUgc291cmNlIHRhcmJhbGwgKGBraXJvY3Jldy1zcmMudGFyLmd6YCkuIFdoZW4gc2V0LFxuICAgKiB0aGUgaW5zdGFuY2Ugcm9sZSBpcyBncmFudGVkIGBzMzpHZXRPYmplY3RgIG9uIHRoaXMgb2JqZWN0IE9OTFkuIExlYXZlXG4gICAqIHVuc2V0IHRvIGNsb25lIGZyb20gZ2l0IGluc3RlYWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gY2xvbmUgZnJvbSBnaXQgKHNlZSBraXJvY3Jld1JlcG8gLyBraXJvY3Jld1JlZilcbiAgICovXG4gIHJlYWRvbmx5IHNvdXJjZUJ1Y2tldD86IHN0cmluZztcblxuICAvKipcbiAgICogUzMga2V5IG9mIHRoZSBzb3VyY2UgdGFyYmFsbCB3aXRoaW4ge0BsaW5rIHNvdXJjZUJ1Y2tldH0uIFJlcXVpcmVkIHdoZW5cbiAgICogYHNvdXJjZUJ1Y2tldGAgaXMgc2V0OyBpZ25vcmVkIG90aGVyd2lzZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBub25lXG4gICAqL1xuICByZWFkb25seSBzb3VyY2VLZXk/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEdpdCByZXBvc2l0b3J5IHRvIGNsb25lIHdoZW4gbm8gUzMgc291cmNlIGlzIGNvbmZpZ3VyZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0ICdodHRwczovL2dpdGh1Yi5jb20va2lyb2RvdGRldi9LaXJvQ3Jldy5naXQnXG4gICAqL1xuICByZWFkb25seSBraXJvY3Jld1JlcG8/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEdpdCByZWYgKGJyYW5jaCBvciB0YWcpIHRvIGluc3RhbGwgd2hlbiBjbG9uaW5nLlxuICAgKlxuICAgKiBQaW4gdGhpcyB0byBhIHJlbGVhc2VkIHRhZyBmb3IgcmVwcm9kdWNpYmxlLCB2ZXJzaW9uLWNvbnRyb2xsZWQgZGVwbG95cyDigJRcbiAgICogdGhlIHVwc3RyZWFtIGxhdW5jaGVyIGRlZmF1bHRzIHRvIGBtYWluYCwgd2hpY2ggZHJpZnRzLiBUaGlzIGNvbnN0cnVjdFxuICAgKiBkZWZhdWx0cyB0byBgbWFpbmAgb25seSB0byBtYXRjaCB1cHN0cmVhbTsgU0VUIElUIHRvIGEgdGFnIGluIHByb2R1Y3Rpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0ICdtYWluJ1xuICAgKi9cbiAgcmVhZG9ubHkga2lyb2NyZXdSZWY/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogRXhwb3NlcyB0aGUgZ2F0ZXdheSdzIHdlYmhvb2sgcG9ydCB0byBPTkUgc291cmNlIHNlY3VyaXR5IGdyb3VwLlxuICpcbiAqIFRoZXJlIGlzIGRlbGliZXJhdGVseSBubyBDSURSIGZvcm06IHRoZSBicmFpbiBib3ggaXMgbmV2ZXIgaW50ZXJuZXQtXG4gKiByZWFjaGFibGUgYnkgY29udHJhY3QuIFRoZSBuYW1lZCBzb3VyY2UgU0cgKGUuZy4gYW4gaW5nZXN0IExhbWJkYSdzIFNHLCBvciBhXG4gKiByZXZlcnNlIHByb3h5IHRoYXQgZnJvbnRzIHRoZSBsb29wYmFjayBnYXRld2F5KSBpcyB0aGUgb25seSBwZWVyIGFsbG93ZWQgdG9cbiAqIHJlYWNoIHRoZSBwb3J0LlxuICpcbiAqIE5PVEU6IHRoZSBLaXJvQ3JldyBnYXRld2F5IGJpbmRzIGxvb3BiYWNrIChgMTI3LjAuMC4xYCkgb25seSDigJQgaXQgZXhwb3NlcyBub1xuICogcm91dGFibGUgbGlzdGVuZXIuIFRoaXMgcnVsZSBvcGVucyB0aGUgc2VjdXJpdHkgZ3JvdXAgc28gYSBjb25zdW1lci1vd25lZFxuICogcmV2ZXJzZSBwcm94eSAvIHR1bm5lbCBvbiB0aGUgYm94IGNhbiBiZSByZWFjaGVkIGZyb20gdGhlIHNvdXJjZSBTRzsgYWN0dWFsbHlcbiAqIHNlcnZpbmcgdGhlIHdlYmhvb2sgb24gYSByb3V0YWJsZSBpbnRlcmZhY2UgaXMgdGhlIGNvbnN1bWVyJ3MgY29uY2VybiAoc2VlXG4gKiBSRUFETUUgXCJQcml2YXRlIGR1YWwtc3RhY2sgYnJhaW5cIiBhbmQgdGhlIHdlYmhvb2sgRGVjaXNpb25zLWZvci1yZXZpZXcpLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFdlYmhvb2tJbmdyZXNzIHtcbiAgLyoqXG4gICAqIEltcG9ydGVkIHNlY3VyaXR5IGdyb3VwIGFsbG93ZWQgdG8gcmVhY2ggdGhlIHdlYmhvb2sgcG9ydC4gUGFzc2VkIGFzIGFuXG4gICAqIGBJU2VjdXJpdHlHcm91cGAgKGltcG9ydGVkKSDigJQgdGhpcyBjb25zdHJ1Y3QgbmV2ZXIgY3JlYXRlcyBpdC5cbiAgICovXG4gIHJlYWRvbmx5IHNvdXJjZTogZWMyLklTZWN1cml0eUdyb3VwO1xuXG4gIC8qKlxuICAgKiBUQ1AgcG9ydCB0aGUgaW5ncmVzcyBydWxlIG9wZW5zLiBEZWZhdWx0cyB0byB0aGUgZGFzaGJvYXJkL2dhdGV3YXkgcG9ydCBzb1xuICAgKiBhIHJldmVyc2UgcHJveHkgZnJvbnRpbmcgdGhlIGxvb3BiYWNrIGdhdGV3YXkgaXMgcmVhY2hhYmxlOyBvdmVycmlkZSB0b1xuICAgKiB0YXJnZXQgYSBjb25zdW1lciBwcm94eSBvbiBhIGRpZmZlcmVudCBwb3J0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHRoZSByZXNvbHZlZCBkYXNoYm9hcmRQb3J0ICg1NDc2KVxuICAgKi9cbiAgcmVhZG9ubHkgcG9ydD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBBbHdheXMtb24gcnVudGltZSBzZXR0aW5ncyBmb3IgdGhlIGhvc3RlZCBjcmV3LCB0aHJlYWRlZCBpbnRvIHRoZSBjcmV3XG4gKiBgY29uZmlnLmpzb25gIGF0IGJvb3QuIEFsbCBmaWVsZHMgYXJlIG9wdGlvbmFsIGFuZCBkZWZhdWx0IHRvIHRoZSBjdXJyZW50XG4gKiBnYXRld2F5IGJlaGF2aW91cjsgb21pdHRpbmcge0BsaW5rIFJlbW90ZUNyZXdJbnN0YW5jZVByb3BzLmNyZXdSdW50aW1lfVxuICogZW50aXJlbHkgcmVwcm9kdWNlcyB0b2RheSdzIGBraXJvY3JldyBzZXR1cCAtLWFnZW50LW9ubHlgICsgYGtpcm9jcmV3XG4gKiBnYXRld2F5YCBleGFjdGx5LlxuICpcbiAqIFZlcmlmaWVkIGFnYWluc3QgS2lyb0NyZXcgdjAuNi4wOiBhdXRvcGlsb3QgbWFwcyB0byBgYWdlbnQuYXBwcm92YWxfbW9kZWAsXG4gKiBpZGxlLWNsb3NlIG1hcHMgdG8gYHNlc3Npb24udGltZW91dF9zZWNzYCwgYW5kIHRoZSBjb25kdWN0b3Igcm9zdGVyIHNoaXBzXG4gKiB3aXRoIGBzZXR1cCAtLWFnZW50LW9ubHlgIChjdXN0b20gbWVtYmVycyBhcmUgc291cmNlLWRlbGl2ZXJlZCBKU09OIHVuZGVyXG4gKiBgfi8ua2lyby9hZ2VudHMvYCkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ3Jld1J1bnRpbWUge1xuICAvKipcbiAgICogRW5hYmxlIEF1dG9waWxvdDogdGhlIGhvc3RlZCBjcmV3IGF1dG8tYXBwcm92ZXMgdG9vbCBjYWxscyB0aGF0IHBhc3MgaXRzXG4gICAqIHNlY3VyaXR5IGNoZWNrcyAoZGVueSBydWxlcyBhbmQgc2Vuc2l0aXZlLXBhdGggYmxvY2tzIHN0aWxsIGFwcGx5KS4gU2V0c1xuICAgKiBgYWdlbnQuYXBwcm92YWxfbW9kZWAgdG8gYFwiYXV0b1wiYCBpbiBjb25maWcuanNvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2UgKGludGVyYWN0aXZlOyBnYXRld2F5IGRlZmF1bHQpXG4gICAqL1xuICByZWFkb25seSBhdXRvcGlsb3Q/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBLZWVwIHRoZSAyNC83IGJyYWluIHNlc3Npb24gYWxpdmUgYmV0d2VlbiBldmVudHMgYnkgZGlzYWJsaW5nIHRoZSBpZGxlXG4gICAqIHNlc3Npb24gc3dlZXAuIFNldHMgYHNlc3Npb24udGltZW91dF9zZWNzYCB0byBgMGAgKGRvY3VtZW50ZWQ6IFwiMCBkaXNhYmxlc1xuICAgKiB0aGUgaWRsZSBzd2VlcFwiKS5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2UgKGRlZmF1bHQgMzYwMHMgaWRsZSB0aW1lb3V0IGFwcGxpZXMpXG4gICAqL1xuICByZWFkb25seSBkaXNhYmxlSWRsZUNsb3NlPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciB7QGxpbmsgUmVtb3RlQ3Jld0luc3RhbmNlfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZW1vdGVDcmV3SW5zdGFuY2VQcm9wcyB7XG4gIC8qKlxuICAgKiBWUEMgdG8gbGF1bmNoIHRoZSBpbnN0YW5jZSBpbnRvLlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjOiBlYzIuSVZwYztcblxuICAvKipcbiAgICogQVJOIG9mIGFuIElBTSBwZXJtaXNzaW9ucyBib3VuZGFyeSBhcHBsaWVkIHRvIHRoZSBpbnN0YW5jZSByb2xlLlxuICAgKlxuICAgKiBUaGUgaW5zdGFuY2UgcnVucyBhIHByb21wdC1pbmplY3RhYmxlIGFnZW50IHRoYXQgZXhlY3V0ZXMgYXJiaXRyYXJ5XG4gICAqIHRvb2xzLCBzbyBpdHMgcm9sZSBNVVNUIGNhcnJ5IGEgYm91bmRhcnkgdGhhdCBjYXBzIGJsYXN0IHJhZGl1cy4gVGhpcyBpc1xuICAgKiByZXF1aXJlZCwgbm90IG9wdGlvbmFsLlxuICAgKi9cbiAgcmVhZG9ubHkgcGVybWlzc2lvbnNCb3VuZGFyeUFybjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTdWJuZXQgc2VsZWN0aW9uIGZvciB0aGUgaW5zdGFuY2UuIEEgcHVibGljIChJR1ctcm91dGVkKSBzdWJuZXQgbmVlZHMgYVxuICAgKiBwdWJsaWMgSVAgZm9yIGVncmVzczsgYSBwcml2YXRlIChOQVQtcm91dGVkKSBzdWJuZXQgZG9lcyBub3Qg4oCUIHNlZVxuICAgKiB7QGxpbmsgYXNzb2NpYXRlUHVibGljSXB9LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG9uZSBwdWJsaWMgc3VibmV0IGluIHRoZSBWUENcbiAgICovXG4gIHJlYWRvbmx5IHZwY1N1Ym5ldHM/OiBlYzIuU3VibmV0U2VsZWN0aW9uO1xuXG4gIC8qKlxuICAgKiBFQzIgaW5zdGFuY2UgdHlwZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBtN2cuMnhsYXJnZSAoYXJtNjQpIC8gbTdpLjJ4bGFyZ2UgKHg4Nl82NCksIG1hdGNoaW5nIHRoZVxuICAgKiB1cHN0cmVhbSBcIkRldmVsb3BtZW50XCIgc2l6ZSB0aWVyXG4gICAqL1xuICByZWFkb25seSBpbnN0YW5jZVR5cGU/OiBlYzIuSW5zdGFuY2VUeXBlO1xuXG4gIC8qKlxuICAgKiBDUFUgYXJjaGl0ZWN0dXJlLiBNdXN0IG1hdGNoIHtAbGluayBpbnN0YW5jZVR5cGV9IHdoZW4gdGhhdCBpcyBzZXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IENyZXdBcmNoaXRlY3R1cmUuQVJNNjRcbiAgICovXG4gIHJlYWRvbmx5IGFyY2hpdGVjdHVyZT86IENyZXdBcmNoaXRlY3R1cmU7XG5cbiAgLyoqXG4gICAqIGdwMyByb290IHZvbHVtZSBzaXplIGluIEdpQiAoMjDigJMxMDAwKS4gVGhlIHZvbHVtZSBpcyBhbHdheXMgZW5jcnlwdGVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCA2MFxuICAgKi9cbiAgcmVhZG9ubHkgdm9sdW1lU2l6ZUdiPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBBdHRhY2ggYSBwdWJsaWMgSVAgdG8gdGhlIGluc3RhbmNlIEVOSS4gUmVxdWlyZWQgZm9yIGVncmVzcyBvbiBJR1ctb25seVxuICAgKiBzdWJuZXRzOyBsZWF2ZSBvZmYgKGZhbHNlKSBmb3IgTkFULXJvdXRlZCBwcml2YXRlIHN1Ym5ldHMsIHdoZXJlIGl0IGlzXG4gICAqIHVudXNlZCBhdHRhY2sgc3VyZmFjZS5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgYXNzb2NpYXRlUHVibGljSXA/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBc3NpZ24gYW4gSVB2NiBhZGRyZXNzIHRvIHRoZSBpbnN0YW5jZSdzIHByaW1hcnkgRU5JIGFuZCBwZXJtaXQgSVB2NlxuICAgKiBlZ3Jlc3Mgb24gdGhlIHNlY3VyaXR5IGdyb3VwLlxuICAgKlxuICAgKiBFbmFibGVzIGEgZHVhbC1zdGFjayBwb3N0dXJlOiBjb21iaW5lZCB3aXRoIGBhc3NvY2lhdGVQdWJsaWNJcDogZmFsc2VgIGFuZFxuICAgKiBhIHByaXZhdGUsIElQdjYtY2FwYWJsZSBzdWJuZXQsIHRoZSBpbnN0YW5jZSBlZ3Jlc3NlcyBvdmVyIElQdjYgKHZpYSB0aGVcbiAgICogVlBDJ3MgRWdyZXNzLU9ubHkgSW50ZXJuZXQgR2F0ZXdheSkgd2l0aCBubyBwdWJsaWMgSVB2NC4gQ0RLJ3NcbiAgICogYGFsbG93QWxsT3V0Ym91bmRgIHJlbmRlcnMgSVB2NCBgMC4wLjAuMC8wYCBlZ3Jlc3Mgb25seSwgc28gdGhpcyBhbHNvIGFkZHNcbiAgICogYW4gZXhwbGljaXQgYWxsLXRyYWZmaWMgSVB2NiBlZ3Jlc3MgcnVsZS5cbiAgICpcbiAgICogVGhpcyBjb25zdHJ1Y3QgZG9lcyBOT1QgcHJvdmlzaW9uIHN1Ym5ldCBJUHY2IENJRFJzLCBhbiBFZ3Jlc3MtT25seVxuICAgKiBJbnRlcm5ldCBHYXRld2F5LCBvciBhbnkgcm91dGUg4oCUIHRob3NlIGFyZSB0aGUgY29uc3VtZXIgVlBDJ3NcbiAgICogcmVzcG9uc2liaWxpdHkuIFRoZSBzZWxlY3RlZCBzdWJuZXQocykgTVVTVCBhbHJlYWR5IGNhcnJ5IElQdjYgQ0lEUnMuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBlbmFibGVJcHY2PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogRGlzY292ZXJ5IHRhZyB2YWx1ZSB3cml0dGVuIGFzIGBraXJvY3JldzppbnN0YW5jZWAuIE11c3QgbWF0Y2hcbiAgICogYFthLXpBLVowLTktXXsxLDUxfWAuXG4gICAqXG4gICAqIEBkZWZhdWx0ICdraXJvY3JldydcbiAgICovXG4gIHJlYWRvbmx5IHN0YWNrVGFnPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUQ1AgcG9ydCB0aGUgZ2F0ZXdheSBzZXJ2ZXMgdGhlIGRhc2hib2FyZCBvbiAobG9vcGJhY2sgb25seTsgcmVhY2hlZCB2aWFcbiAgICogU1NNIHBvcnQtZm9yd2FyZCkuIFJlY29yZGVkIGluIHRoZSBpbnN0YW5jZSByZWdpc3RyeSBhcyB0aGUgcmVtb3RlIHBvcnQuXG4gICAqXG4gICAqIEBkZWZhdWx0IDU0NzZcbiAgICovXG4gIHJlYWRvbmx5IGRhc2hib2FyZFBvcnQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIFNTSCBpbmdyZXNzIENJRFIuIFdoZW4gc2V0IChhbmQgbm8gd2lkZXIgdGhhbiAvMTYpLCBvcGVucyB0Y3AvMjJcbiAgICogZnJvbSB0aGF0IENJRFIgYXMgYSBmYWxsYmFjay4gT21pdCBmb3IgU1NNLW9ubHkgYWNjZXNzIChyZWNvbW1lbmRlZCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gaW5ib3VuZDsgU1NNLW9ubHlcbiAgICovXG4gIHJlYWRvbmx5IGFsbG93U3NoQ2lkcj86IHN0cmluZztcblxuICAvKipcbiAgICogT3BlbiB0aGUgZ2F0ZXdheS93ZWJob29rIHBvcnQgdG8gT05FIHNvdXJjZSBzZWN1cml0eSBncm91cCBvbmx5IChuZXZlciBhXG4gICAqIENJRFIpLiBJbmRlcGVuZGVudCBvZiB7QGxpbmsgYWxsb3dTc2hDaWRyfSDigJQgYm90aCwgZWl0aGVyLCBvciBuZWl0aGVyIG1heVxuICAgKiBiZSBzZXQ7IHVuc2V0IGxlYXZlcyB0aGUgU0cgbm8taW5ib3VuZCAodGhlIGRlZmF1bHQpLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIHdlYmhvb2sgaW5ncmVzc1xuICAgKi9cbiAgcmVhZG9ubHkgd2ViaG9va0luZ3Jlc3M/OiBXZWJob29rSW5ncmVzcztcblxuICAvKipcbiAgICogU2VjcmV0cyBNYW5hZ2VyIEFSTiBvZiB0aGUgQmVhcmVyIHRva2VuIHRoYXQgYXV0aGVudGljYXRlcyB0aGUgbmF0aXZlXG4gICAqIHdlYmhvb2sgKGBQT1NUIC9hcGkvaG9va3MvYWdlbnRgKS4gQXQgYm9vdCB0aGUgaW5zdGFuY2UgZmV0Y2hlcyB0aGUgc2VjcmV0XG4gICAqIGFuZCB3cml0ZXMgaXQgYXMgYGhvb2tzLndlYmhvb2tfdG9rZW5gIGluIHRoZSBjcmV3IGBjb25maWcuanNvbmAg4oCUIHRoZVxuICAgKiB0b2tlbiBpcyBuZXZlciBiYWtlZCBpbnRvIHVzZXJEYXRhLCBlbnYgbGl0ZXJhbHMsIG9yIGNvZGUuIFRoZSBpbnN0YW5jZVxuICAgKiByb2xlIGlzIGdyYW50ZWQgYHNlY3JldHNtYW5hZ2VyOkdldFNlY3JldFZhbHVlYCBvbiBUSElTIEFSTiBvbmx5LlxuICAgKlxuICAgKiBSZXF1aXJlZCB3aGVuIHtAbGluayB3ZWJob29rSW5ncmVzc30gaXMgc2V0OiBhIHJlYWNoYWJsZSB3ZWJob29rIHdpdGggbm9cbiAgICogYXV0aCBpcyBhIGRlZmVjdCwgbm90IGEgZGVmYXVsdCwgc28gc3ludGggZmFpbHMgaWYgaW5ncmVzcyBpcyBvcGVuZWRcbiAgICogd2l0aG91dCBhIHRva2VuLlxuICAgKlxuICAgKiBOT1RFOiB0aGUgS2lyb0NyZXcgZ2F0ZXdheSBiaW5kcyBsb29wYmFjayAoYDEyNy4wLjAuMWApIG9ubHkgYW5kIGV4cG9zZXMgbm9cbiAgICogcm91dGFibGUgd2ViaG9vayBsaXN0ZW5lciDigJQgc2VlIHRoZSB3ZWJob29rIERlY2lzaW9ucy1mb3ItcmV2aWV3IGluIHRoZSBQUi5cbiAgICogVGhpcyB3aXJlcyB0aGUgQVVUSCAodG9rZW4taW4tY29uZmlnKTsgcm91dGFibGUgZXhwb3N1cmUgb2YgdGhlIGxvb3BiYWNrXG4gICAqIHJvdXRlIGlzIGEgY29uc3VtZXIgcmV2ZXJzZS1wcm94eSAvIHR1bm5lbCBjb25jZXJuLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHdlYmhvb2sgYXV0aCBub3QgY29uZmlndXJlZCAobG9vcGJhY2sgLyBTU00gb25seSlcbiAgICovXG4gIHJlYWRvbmx5IHdlYmhvb2tUb2tlblNlY3JldEFybj86IHN0cmluZztcblxuICAvKipcbiAgICogQWx3YXlzLW9uIHJ1bnRpbWUgc2V0dGluZ3MgKEF1dG9waWxvdCwgbm8taWRsZS1jbG9zZSkgZm9yIHRoZSBob3N0ZWQgY3JldyxcbiAgICogdGhyZWFkZWQgaW50byBjb25maWcuanNvbiBhdCBib290LiBPbWl0IGZvciB0aGUgY3VycmVudCBnYXRld2F5IGRlZmF1bHRzLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGN1cnJlbnQgZ2F0ZXdheSBiZWhhdmlvdXIgKGludGVyYWN0aXZlLCAzNjAwcyBpZGxlIHRpbWVvdXQpXG4gICAqL1xuICByZWFkb25seSBjcmV3UnVudGltZT86IENyZXdSdW50aW1lO1xuXG4gIC8qKlxuICAgKiBIb3cgdGhlIEtpcm9DcmV3IHNvdXJjZSByZWFjaGVzIHRoZSBpbnN0YW5jZSAoUzMgdGFyYmFsbCBvciBnaXQgY2xvbmUpLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGNsb25lIGtpcm9kb3RkZXYvS2lyb0NyZXdAbWFpblxuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlPzogQ3Jld1NvdXJjZTtcblxuICAvKipcbiAgICogTWludXRlcyB0byB3YWl0IGZvciB0aGUgZ2F0ZXdheSB0byBiZWNvbWUgaGVhbHRoeSBiZWZvcmUgdGhlIHN0YWNrIGZhaWxzXG4gICAqIGFuZCByb2xscyBiYWNrIChjb2xkIGJvb3QgKyBkbmYgKyBOb2RlICsgdml0ZSBidWlsZCArIHBpcCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IDI1XG4gICAqL1xuICByZWFkb25seSBib290c3RyYXBUaW1lb3V0TWludXRlcz86IG51bWJlcjtcblxuICAvKipcbiAgICogQW4gUzMgYmFja3VwIGJ1Y2tldCB0byBwdXNoIGNyZXcgc25hcHNob3RzIHRvIG9uIGEgc2NoZWR1bGUuIFdoZW4gc2V0LCB0aGVcbiAgICogaW5zdGFuY2Ugcm9sZSBpcyBncmFudGVkIHdyaXRlLCBhIHN5c3RlbWQgdGltZXIgcnVuc1xuICAgKiBga2lyb2NyZXcgc25hcHNob3QgLS1wdXJwb3NlIGJhY2t1cGAgYW5kIHVwbG9hZHMgdGhlIG5ld2VzdCAocmVkYWN0aW9uLVxuICAgKiBzY3J1YmJlZCkgYnVuZGxlLCBhbmQgYSBga2lyb2NyZXctcmVzdG9yZS1mcm9tLXMzYCBoZWxwZXIgaXMgaW5zdGFsbGVkIGZvclxuICAgKiByZWJ1aWxkaW5nIGEgcmVwbGFjZW1lbnQgaW5zdGFuY2UuIE9taXQgdG8gZGlzYWJsZSBvZmYtYm94IGJhY2t1cC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBvZmYtYm94IGJhY2t1cFxuICAgKi9cbiAgcmVhZG9ubHkgYmFja3VwQnVja2V0PzogSUNyZXdCYWNrdXBCdWNrZXQ7XG5cbiAgLyoqXG4gICAqIHN5c3RlbWQgT25DYWxlbmRhciBleHByZXNzaW9uIGZvciB0aGUgYmFja3VwIHRpbWVyIChzZWVcbiAgICogYG1hbiBzeXN0ZW1kLnRpbWVgKS4gT25seSB1c2VkIHdoZW4ge0BsaW5rIGJhY2t1cEJ1Y2tldH0gaXMgc2V0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAnZGFpbHknXG4gICAqL1xuICByZWFkb25seSBiYWNrdXBTY2hlZHVsZT86IHN0cmluZztcblxuICAvKipcbiAgICogUzMga2V5IHByZWZpeCB1bmRlciB3aGljaCBzbmFwc2hvdHMgYXJlIHN0b3JlZCBpbiB0aGUgYmFja3VwIGJ1Y2tldC5cbiAgICogT25seSB1c2VkIHdoZW4ge0BsaW5rIGJhY2t1cEJ1Y2tldH0gaXMgc2V0LiBBIHRyYWlsaW5nIHNsYXNoIGlzIGFkZGVkIGlmXG4gICAqIGFic2VudC5cbiAgICpcbiAgICogQGRlZmF1bHQgJ2NyZXctc25hcHNob3RzLydcbiAgICovXG4gIHJlYWRvbmx5IGJhY2t1cFByZWZpeD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgc3Vic2V0IG9mIHtAbGluayBDcmV3QmFja3VwQnVja2V0fSB0aGUgRUMyL0ZhcmdhdGUgY29uc3RydWN0cyBuZWVkLiBLZXB0XG4gKiBhcyBhbiBpbnRlcmZhY2Ugc28gYSBjb25zdW1lciBjYW4gcGFzcyB0aGVpciBvd24gYnVja2V0IHdyYXBwZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSUNyZXdCYWNrdXBCdWNrZXQge1xuICAvKiogVGhlIGRlc3RpbmF0aW9uIGJ1Y2tldCBuYW1lLiAqL1xuICByZWFkb25seSBidWNrZXQ6IHMzLklCdWNrZXQ7XG4gIC8qKiBHcmFudCBhIHByaW5jaXBhbCB3cml0ZSBhY2Nlc3MgdG8gc25hcHNob3RzIChidWNrZXQgKyBLTVMpLiAqL1xuICBncmFudFdyaXRlKGdyYW50ZWU6IGlhbS5JR3JhbnRhYmxlKTogdm9pZDtcbiAgLyoqIEdyYW50IGEgcHJpbmNpcGFsIHJlYWQgYWNjZXNzIHRvIHNuYXBzaG90cyAoYnVja2V0ICsgS01TKS4gKi9cbiAgZ3JhbnRSZWFkKGdyYW50ZWU6IGlhbS5JR3JhbnRhYmxlKTogdm9pZDtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
|
2
|
+
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
3
|
+
import { Construct } from 'constructs';
|
|
4
|
+
import { RemoteCrewInstanceProps } from './remote-crew-instance-props';
|
|
5
|
+
/**
|
|
6
|
+
* A self-hosted KiroCrew gateway on a single EC2 instance, reached over SSM
|
|
7
|
+
* Session Manager with no inbound ports.
|
|
8
|
+
*
|
|
9
|
+
* This is a pipeline-native, version-controlled CDK port of the upstream
|
|
10
|
+
* `kirocrew-ec2` CloudFormation template
|
|
11
|
+
* (github.com/kirodotdev/KiroCrew). It provisions the same shape — an IAM
|
|
12
|
+
* role (SSM core + optional scoped S3 read) under a required permissions
|
|
13
|
+
* boundary, an SSM-only security group, an IMDSv2-enforced instance on an
|
|
14
|
+
* encrypted gp3 volume, and a WaitCondition that blocks stack completion
|
|
15
|
+
* until the gateway is serving — but under your naming, boundary, and
|
|
16
|
+
* deploy pipeline instead of an imperative `kirocrew cloud launch`.
|
|
17
|
+
*
|
|
18
|
+
* Access is via SSM port-forward only; the public DNS output is for
|
|
19
|
+
* diagnostics.
|
|
20
|
+
*/
|
|
21
|
+
export declare class RemoteCrewInstance extends Construct {
|
|
22
|
+
/** The EC2 instance (SSM target). */
|
|
23
|
+
readonly instance: ec2.Instance;
|
|
24
|
+
/** The instance's IAM role (carries the permissions boundary). */
|
|
25
|
+
readonly role: iam.Role;
|
|
26
|
+
/** The SSM-only security group (no inbound unless allowSshCidr is set). */
|
|
27
|
+
readonly securityGroup: ec2.SecurityGroup;
|
|
28
|
+
/** The discovery tag value written as `kirocrew:instance`. */
|
|
29
|
+
readonly stackTag: string;
|
|
30
|
+
constructor(scope: Construct, id: string, props: RemoteCrewInstanceProps);
|
|
31
|
+
/** Public DNS of the instance (diagnostics only; access is via SSM). */
|
|
32
|
+
get publicDnsName(): string;
|
|
33
|
+
/** Instance id — the SSM target. */
|
|
34
|
+
get instanceId(): string;
|
|
35
|
+
}
|