@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.
@@ -0,0 +1,68 @@
1
+ import * as ec2 from 'aws-cdk-lib/aws-ec2';
2
+ import * as ecs from 'aws-cdk-lib/aws-ecs';
3
+ import { Construct } from 'constructs';
4
+ /**
5
+ * CPU architecture a crew container image was built for. Must match the image:
6
+ * a task whose runtime platform disagrees with its image fails at start.
7
+ */
8
+ export declare enum FargateCpuArchitecture {
9
+ X86_64 = "X86_64",
10
+ ARM64 = "ARM64"
11
+ }
12
+ /**
13
+ * Properties for {@link FargateCrewBase}.
14
+ */
15
+ export interface FargateCrewBaseProps {
16
+ /**
17
+ * VPC the crew tasks are placed in.
18
+ */
19
+ readonly vpc: ec2.IVpc;
20
+ /**
21
+ * Subnets for the tasks' awsvpc network interfaces. Each must be able to
22
+ * reach the container registry — a NAT-routed private subnet, or a public
23
+ * subnet with `assignPublicIp` at RunTask.
24
+ *
25
+ * Networking is taken, never invented: whether egress is via NAT or a public
26
+ * subnet is a property of the operator's VPC this construct cannot discover,
27
+ * so it is passed in and echoed as an output for the launch spec.
28
+ *
29
+ * @default - the VPC's private-with-egress subnets
30
+ */
31
+ readonly vpcSubnets?: ec2.SubnetSelection;
32
+ /**
33
+ * Architecture the crew image was built for. Surfaced as an output for the
34
+ * launch spec so every placement field is read from a stack, not the
35
+ * operator's memory.
36
+ *
37
+ * @default FargateCpuArchitecture.X86_64
38
+ */
39
+ readonly cpuArchitecture?: FargateCpuArchitecture;
40
+ /**
41
+ * Discovery tag value written as `kirocrew:fargate`. Must match
42
+ * `[a-zA-Z0-9-]{1,51}`. The cluster is named `kirocrew-crew-<stackTag>`.
43
+ *
44
+ * @default 'kirocrew'
45
+ */
46
+ readonly stackTag?: string;
47
+ }
48
+ /**
49
+ * Shared Fargate scaffolding for KiroCrew remote crews: the ECS cluster every
50
+ * crew task runs on and the egress-only security group they are placed in.
51
+ *
52
+ * ONE per account and region. The per-crew roles and log group live in
53
+ * {@link FargateCrew} (one per crew), so deleting a crew cannot delete the
54
+ * cluster its siblings run on.
55
+ *
56
+ * Port of the upstream `kirocrew-fargate-base` CloudFormation template.
57
+ */
58
+ export declare class FargateCrewBase extends Construct {
59
+ /** The ECS cluster crew tasks run on. */
60
+ readonly cluster: ecs.Cluster;
61
+ /** The egress-only task security group (no inbound). */
62
+ readonly securityGroup: ec2.SecurityGroup;
63
+ /** The `kirocrew:fargate` discovery tag value. */
64
+ readonly stackTag: string;
65
+ /** The architecture crew images must be built for. */
66
+ readonly cpuArchitecture: FargateCpuArchitecture;
67
+ constructor(scope: Construct, id: string, props: FargateCrewBaseProps);
68
+ }
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.FargateCrewBase = exports.FargateCpuArchitecture = void 0;
37
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
38
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
39
+ const ec2 = __importStar(require("aws-cdk-lib/aws-ec2"));
40
+ const ecs = __importStar(require("aws-cdk-lib/aws-ecs"));
41
+ const constructs_1 = require("constructs");
42
+ const STACK_TAG_RE = /^[a-zA-Z0-9-]{1,51}$/;
43
+ /**
44
+ * CPU architecture a crew container image was built for. Must match the image:
45
+ * a task whose runtime platform disagrees with its image fails at start.
46
+ */
47
+ var FargateCpuArchitecture;
48
+ (function (FargateCpuArchitecture) {
49
+ FargateCpuArchitecture["X86_64"] = "X86_64";
50
+ FargateCpuArchitecture["ARM64"] = "ARM64";
51
+ })(FargateCpuArchitecture || (exports.FargateCpuArchitecture = FargateCpuArchitecture = {}));
52
+ /**
53
+ * Shared Fargate scaffolding for KiroCrew remote crews: the ECS cluster every
54
+ * crew task runs on and the egress-only security group they are placed in.
55
+ *
56
+ * ONE per account and region. The per-crew roles and log group live in
57
+ * {@link FargateCrew} (one per crew), so deleting a crew cannot delete the
58
+ * cluster its siblings run on.
59
+ *
60
+ * Port of the upstream `kirocrew-fargate-base` CloudFormation template.
61
+ */
62
+ class FargateCrewBase extends constructs_1.Construct {
63
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@raindancers/raindancers-crew.FargateCrewBase", version: "0.0.0" };
64
+ /** The ECS cluster crew tasks run on. */
65
+ cluster;
66
+ /** The egress-only task security group (no inbound). */
67
+ securityGroup;
68
+ /** The `kirocrew:fargate` discovery tag value. */
69
+ stackTag;
70
+ /** The architecture crew images must be built for. */
71
+ cpuArchitecture;
72
+ constructor(scope, id, props) {
73
+ super(scope, id);
74
+ const stackTag = props.stackTag ?? 'kirocrew';
75
+ if (!STACK_TAG_RE.test(stackTag)) {
76
+ throw new Error(`stackTag must match ${STACK_TAG_RE} (got '${stackTag}')`);
77
+ }
78
+ this.stackTag = stackTag;
79
+ this.cpuArchitecture = props.cpuArchitecture ?? FargateCpuArchitecture.X86_64;
80
+ // Named from the tag (not discovered) so a launcher can derive it, and to
81
+ // keep tasks out of the account's implicit `default` cluster.
82
+ this.cluster = new ecs.Cluster(this, 'Cluster', {
83
+ vpc: props.vpc,
84
+ clusterName: `kirocrew-crew-${stackTag}`,
85
+ containerInsightsV2: ecs.ContainerInsights.DISABLED,
86
+ });
87
+ // No ingress at all. The crew's control surface is reached
88
+ // outbound-authenticated; nothing needs to dial in. Egress open so the
89
+ // task can pull its image and reach the model endpoint.
90
+ this.securityGroup = new ec2.SecurityGroup(this, 'TaskSecurityGroup', {
91
+ vpc: props.vpc,
92
+ description: `Kiro Crew Fargate crews ${stackTag} - egress only, no inbound`,
93
+ allowAllOutbound: true,
94
+ });
95
+ for (const taggable of [this.cluster, this.securityGroup]) {
96
+ aws_cdk_lib_1.Tags.of(taggable).add('kirocrew:managed', 'true');
97
+ aws_cdk_lib_1.Tags.of(taggable).add('kirocrew:fargate', stackTag);
98
+ }
99
+ }
100
+ }
101
+ exports.FargateCrewBase = FargateCrewBase;
102
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFyZ2F0ZS1jcmV3LWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZmFyZ2F0ZS1jcmV3LWJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDZDQUFtQztBQUNuQyx5REFBMkM7QUFDM0MseURBQTJDO0FBQzNDLDJDQUF1QztBQUV2QyxNQUFNLFlBQVksR0FBRyxzQkFBc0IsQ0FBQztBQUU1Qzs7O0dBR0c7QUFDSCxJQUFZLHNCQUdYO0FBSEQsV0FBWSxzQkFBc0I7SUFDaEMsMkNBQWlCLENBQUE7SUFDakIseUNBQWUsQ0FBQTtBQUNqQixDQUFDLEVBSFcsc0JBQXNCLHNDQUF0QixzQkFBc0IsUUFHakM7QUEwQ0Q7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBYSxlQUFnQixTQUFRLHNCQUFTOztJQUM1Qyx5Q0FBeUM7SUFDekIsT0FBTyxDQUFjO0lBQ3JDLHdEQUF3RDtJQUN4QyxhQUFhLENBQW9CO0lBQ2pELGtEQUFrRDtJQUNsQyxRQUFRLENBQVM7SUFDakMsc0RBQXNEO0lBQ3RDLGVBQWUsQ0FBeUI7SUFFeEQsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUEyQjtRQUNuRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLElBQUksVUFBVSxDQUFDO1FBQzlDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDakMsTUFBTSxJQUFJLEtBQUssQ0FBQyx1QkFBdUIsWUFBWSxVQUFVLFFBQVEsSUFBSSxDQUFDLENBQUM7UUFDN0UsQ0FBQztRQUNELElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDLGVBQWUsSUFBSSxzQkFBc0IsQ0FBQyxNQUFNLENBQUM7UUFFOUUsMEVBQTBFO1FBQzFFLDhEQUE4RDtRQUM5RCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFO1lBQzlDLEdBQUcsRUFBRSxLQUFLLENBQUMsR0FBRztZQUNkLFdBQVcsRUFBRSxpQkFBaUIsUUFBUSxFQUFFO1lBQ3hDLG1CQUFtQixFQUFFLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRO1NBQ3BELENBQUMsQ0FBQztRQUVILDJEQUEyRDtRQUMzRCx1RUFBdUU7UUFDdkUsd0RBQXdEO1FBQ3hELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxHQUFHLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxtQkFBbUIsRUFBRTtZQUNwRSxHQUFHLEVBQUUsS0FBSyxDQUFDLEdBQUc7WUFDZCxXQUFXLEVBQUUsMkJBQTJCLFFBQVEsNEJBQTRCO1lBQzVFLGdCQUFnQixFQUFFLElBQUk7U0FDdkIsQ0FBQyxDQUFDO1FBRUgsS0FBSyxNQUFNLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7WUFDMUQsa0JBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ2xELGtCQUFJLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN0RCxDQUFDO0lBQ0gsQ0FBQzs7QUF6Q0gsMENBMENDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVGFncyB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGVjMiBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWMyJztcbmltcG9ydCAqIGFzIGVjcyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWNzJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG5jb25zdCBTVEFDS19UQUdfUkUgPSAvXlthLXpBLVowLTktXXsxLDUxfSQvO1xuXG4vKipcbiAqIENQVSBhcmNoaXRlY3R1cmUgYSBjcmV3IGNvbnRhaW5lciBpbWFnZSB3YXMgYnVpbHQgZm9yLiBNdXN0IG1hdGNoIHRoZSBpbWFnZTpcbiAqIGEgdGFzayB3aG9zZSBydW50aW1lIHBsYXRmb3JtIGRpc2FncmVlcyB3aXRoIGl0cyBpbWFnZSBmYWlscyBhdCBzdGFydC5cbiAqL1xuZXhwb3J0IGVudW0gRmFyZ2F0ZUNwdUFyY2hpdGVjdHVyZSB7XG4gIFg4Nl82NCA9ICdYODZfNjQnLFxuICBBUk02NCA9ICdBUk02NCcsXG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3Ige0BsaW5rIEZhcmdhdGVDcmV3QmFzZX0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRmFyZ2F0ZUNyZXdCYXNlUHJvcHMge1xuICAvKipcbiAgICogVlBDIHRoZSBjcmV3IHRhc2tzIGFyZSBwbGFjZWQgaW4uXG4gICAqL1xuICByZWFkb25seSB2cGM6IGVjMi5JVnBjO1xuXG4gIC8qKlxuICAgKiBTdWJuZXRzIGZvciB0aGUgdGFza3MnIGF3c3ZwYyBuZXR3b3JrIGludGVyZmFjZXMuIEVhY2ggbXVzdCBiZSBhYmxlIHRvXG4gICAqIHJlYWNoIHRoZSBjb250YWluZXIgcmVnaXN0cnkg4oCUIGEgTkFULXJvdXRlZCBwcml2YXRlIHN1Ym5ldCwgb3IgYSBwdWJsaWNcbiAgICogc3VibmV0IHdpdGggYGFzc2lnblB1YmxpY0lwYCBhdCBSdW5UYXNrLlxuICAgKlxuICAgKiBOZXR3b3JraW5nIGlzIHRha2VuLCBuZXZlciBpbnZlbnRlZDogd2hldGhlciBlZ3Jlc3MgaXMgdmlhIE5BVCBvciBhIHB1YmxpY1xuICAgKiBzdWJuZXQgaXMgYSBwcm9wZXJ0eSBvZiB0aGUgb3BlcmF0b3IncyBWUEMgdGhpcyBjb25zdHJ1Y3QgY2Fubm90IGRpc2NvdmVyLFxuICAgKiBzbyBpdCBpcyBwYXNzZWQgaW4gYW5kIGVjaG9lZCBhcyBhbiBvdXRwdXQgZm9yIHRoZSBsYXVuY2ggc3BlYy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB0aGUgVlBDJ3MgcHJpdmF0ZS13aXRoLWVncmVzcyBzdWJuZXRzXG4gICAqL1xuICByZWFkb25seSB2cGNTdWJuZXRzPzogZWMyLlN1Ym5ldFNlbGVjdGlvbjtcblxuICAvKipcbiAgICogQXJjaGl0ZWN0dXJlIHRoZSBjcmV3IGltYWdlIHdhcyBidWlsdCBmb3IuIFN1cmZhY2VkIGFzIGFuIG91dHB1dCBmb3IgdGhlXG4gICAqIGxhdW5jaCBzcGVjIHNvIGV2ZXJ5IHBsYWNlbWVudCBmaWVsZCBpcyByZWFkIGZyb20gYSBzdGFjaywgbm90IHRoZVxuICAgKiBvcGVyYXRvcidzIG1lbW9yeS5cbiAgICpcbiAgICogQGRlZmF1bHQgRmFyZ2F0ZUNwdUFyY2hpdGVjdHVyZS5YODZfNjRcbiAgICovXG4gIHJlYWRvbmx5IGNwdUFyY2hpdGVjdHVyZT86IEZhcmdhdGVDcHVBcmNoaXRlY3R1cmU7XG5cbiAgLyoqXG4gICAqIERpc2NvdmVyeSB0YWcgdmFsdWUgd3JpdHRlbiBhcyBga2lyb2NyZXc6ZmFyZ2F0ZWAuIE11c3QgbWF0Y2hcbiAgICogYFthLXpBLVowLTktXXsxLDUxfWAuIFRoZSBjbHVzdGVyIGlzIG5hbWVkIGBraXJvY3Jldy1jcmV3LTxzdGFja1RhZz5gLlxuICAgKlxuICAgKiBAZGVmYXVsdCAna2lyb2NyZXcnXG4gICAqL1xuICByZWFkb25seSBzdGFja1RhZz86IHN0cmluZztcbn1cblxuLyoqXG4gKiBTaGFyZWQgRmFyZ2F0ZSBzY2FmZm9sZGluZyBmb3IgS2lyb0NyZXcgcmVtb3RlIGNyZXdzOiB0aGUgRUNTIGNsdXN0ZXIgZXZlcnlcbiAqIGNyZXcgdGFzayBydW5zIG9uIGFuZCB0aGUgZWdyZXNzLW9ubHkgc2VjdXJpdHkgZ3JvdXAgdGhleSBhcmUgcGxhY2VkIGluLlxuICpcbiAqIE9ORSBwZXIgYWNjb3VudCBhbmQgcmVnaW9uLiBUaGUgcGVyLWNyZXcgcm9sZXMgYW5kIGxvZyBncm91cCBsaXZlIGluXG4gKiB7QGxpbmsgRmFyZ2F0ZUNyZXd9IChvbmUgcGVyIGNyZXcpLCBzbyBkZWxldGluZyBhIGNyZXcgY2Fubm90IGRlbGV0ZSB0aGVcbiAqIGNsdXN0ZXIgaXRzIHNpYmxpbmdzIHJ1biBvbi5cbiAqXG4gKiBQb3J0IG9mIHRoZSB1cHN0cmVhbSBga2lyb2NyZXctZmFyZ2F0ZS1iYXNlYCBDbG91ZEZvcm1hdGlvbiB0ZW1wbGF0ZS5cbiAqL1xuZXhwb3J0IGNsYXNzIEZhcmdhdGVDcmV3QmFzZSBleHRlbmRzIENvbnN0cnVjdCB7XG4gIC8qKiBUaGUgRUNTIGNsdXN0ZXIgY3JldyB0YXNrcyBydW4gb24uICovXG4gIHB1YmxpYyByZWFkb25seSBjbHVzdGVyOiBlY3MuQ2x1c3RlcjtcbiAgLyoqIFRoZSBlZ3Jlc3Mtb25seSB0YXNrIHNlY3VyaXR5IGdyb3VwIChubyBpbmJvdW5kKS4gKi9cbiAgcHVibGljIHJlYWRvbmx5IHNlY3VyaXR5R3JvdXA6IGVjMi5TZWN1cml0eUdyb3VwO1xuICAvKiogVGhlIGBraXJvY3JldzpmYXJnYXRlYCBkaXNjb3ZlcnkgdGFnIHZhbHVlLiAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc3RhY2tUYWc6IHN0cmluZztcbiAgLyoqIFRoZSBhcmNoaXRlY3R1cmUgY3JldyBpbWFnZXMgbXVzdCBiZSBidWlsdCBmb3IuICovXG4gIHB1YmxpYyByZWFkb25seSBjcHVBcmNoaXRlY3R1cmU6IEZhcmdhdGVDcHVBcmNoaXRlY3R1cmU7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IEZhcmdhdGVDcmV3QmFzZVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGNvbnN0IHN0YWNrVGFnID0gcHJvcHMuc3RhY2tUYWcgPz8gJ2tpcm9jcmV3JztcbiAgICBpZiAoIVNUQUNLX1RBR19SRS50ZXN0KHN0YWNrVGFnKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBzdGFja1RhZyBtdXN0IG1hdGNoICR7U1RBQ0tfVEFHX1JFfSAoZ290ICcke3N0YWNrVGFnfScpYCk7XG4gICAgfVxuICAgIHRoaXMuc3RhY2tUYWcgPSBzdGFja1RhZztcbiAgICB0aGlzLmNwdUFyY2hpdGVjdHVyZSA9IHByb3BzLmNwdUFyY2hpdGVjdHVyZSA/PyBGYXJnYXRlQ3B1QXJjaGl0ZWN0dXJlLlg4Nl82NDtcblxuICAgIC8vIE5hbWVkIGZyb20gdGhlIHRhZyAobm90IGRpc2NvdmVyZWQpIHNvIGEgbGF1bmNoZXIgY2FuIGRlcml2ZSBpdCwgYW5kIHRvXG4gICAgLy8ga2VlcCB0YXNrcyBvdXQgb2YgdGhlIGFjY291bnQncyBpbXBsaWNpdCBgZGVmYXVsdGAgY2x1c3Rlci5cbiAgICB0aGlzLmNsdXN0ZXIgPSBuZXcgZWNzLkNsdXN0ZXIodGhpcywgJ0NsdXN0ZXInLCB7XG4gICAgICB2cGM6IHByb3BzLnZwYyxcbiAgICAgIGNsdXN0ZXJOYW1lOiBga2lyb2NyZXctY3Jldy0ke3N0YWNrVGFnfWAsXG4gICAgICBjb250YWluZXJJbnNpZ2h0c1YyOiBlY3MuQ29udGFpbmVySW5zaWdodHMuRElTQUJMRUQsXG4gICAgfSk7XG5cbiAgICAvLyBObyBpbmdyZXNzIGF0IGFsbC4gVGhlIGNyZXcncyBjb250cm9sIHN1cmZhY2UgaXMgcmVhY2hlZFxuICAgIC8vIG91dGJvdW5kLWF1dGhlbnRpY2F0ZWQ7IG5vdGhpbmcgbmVlZHMgdG8gZGlhbCBpbi4gRWdyZXNzIG9wZW4gc28gdGhlXG4gICAgLy8gdGFzayBjYW4gcHVsbCBpdHMgaW1hZ2UgYW5kIHJlYWNoIHRoZSBtb2RlbCBlbmRwb2ludC5cbiAgICB0aGlzLnNlY3VyaXR5R3JvdXAgPSBuZXcgZWMyLlNlY3VyaXR5R3JvdXAodGhpcywgJ1Rhc2tTZWN1cml0eUdyb3VwJywge1xuICAgICAgdnBjOiBwcm9wcy52cGMsXG4gICAgICBkZXNjcmlwdGlvbjogYEtpcm8gQ3JldyBGYXJnYXRlIGNyZXdzICR7c3RhY2tUYWd9IC0gZWdyZXNzIG9ubHksIG5vIGluYm91bmRgLFxuICAgICAgYWxsb3dBbGxPdXRib3VuZDogdHJ1ZSxcbiAgICB9KTtcblxuICAgIGZvciAoY29uc3QgdGFnZ2FibGUgb2YgW3RoaXMuY2x1c3RlciwgdGhpcy5zZWN1cml0eUdyb3VwXSkge1xuICAgICAgVGFncy5vZih0YWdnYWJsZSkuYWRkKCdraXJvY3JldzptYW5hZ2VkJywgJ3RydWUnKTtcbiAgICAgIFRhZ3Mub2YodGFnZ2FibGUpLmFkZCgna2lyb2NyZXc6ZmFyZ2F0ZScsIHN0YWNrVGFnKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,89 @@
1
+ import * as iam from 'aws-cdk-lib/aws-iam';
2
+ import * as logs from 'aws-cdk-lib/aws-logs';
3
+ import { Construct } from 'constructs';
4
+ import { ICrewBackupBucket } from './remote-crew-instance-props';
5
+ /**
6
+ * Properties for {@link FargateCrew}.
7
+ */
8
+ export interface FargateCrewProps {
9
+ /**
10
+ * Crew name: 1–32 chars, lower-case alphanumeric with inner hyphens, never
11
+ * leading or trailing. Every resource name is DERIVED from it — the task
12
+ * definition rebuilds the role ARNs and log-group name from the crew name
13
+ * and refuses a document whose ARNs disagree, so a rename here is a launch
14
+ * refusal, not a silent mismatch.
15
+ */
16
+ readonly crew: string;
17
+ /**
18
+ * Days a crew's task logs are kept before CloudWatch expires them. Must be
19
+ * one of the CloudWatch retention values.
20
+ *
21
+ * @default 30
22
+ */
23
+ readonly logRetentionDays?: number;
24
+ /**
25
+ * ARN of the pre-created shared crew permissions boundary
26
+ * (`arn:aws:iam::<account>:policy/kirocrew-crew-boundary`).
27
+ *
28
+ * Optional by design: this is a DECLARED degraded mode. Unlike the EC2 lane
29
+ * (whose boundary is created once by launcher code), no creator exists for
30
+ * the crew boundary yet, so rather than reference a policy nothing creates
31
+ * this is omitted until that creator lands. When set, it caps what these
32
+ * roles can ever do regardless of attached policies.
33
+ *
34
+ * @default - no boundary (declared degraded mode)
35
+ */
36
+ readonly permissionsBoundaryArn?: string;
37
+ /**
38
+ * ARN of the private ECR repository holding the crew image. Leave unset when
39
+ * the image is pulled from a public registry (the decided delivery, ECR
40
+ * Public), which needs no execution-role pull grant. When set, the pull grant
41
+ * is scoped to this one repository.
42
+ *
43
+ * @default - public registry; no pull grant
44
+ */
45
+ readonly ecrRepositoryArn?: string;
46
+ /**
47
+ * An S3 backup bucket to grant the TASK role write access to, so the running
48
+ * crew container can push `kirocrew snapshot` bundles off-box on its own
49
+ * schedule. The task role (not the execution role) gets this, because the
50
+ * push runs inside the container. Omit to disable off-box backup.
51
+ *
52
+ * @default - no off-box backup grant
53
+ */
54
+ readonly backupBucket?: ICrewBackupBucket;
55
+ }
56
+ /**
57
+ * Per-crew Fargate scaffolding for ONE KiroCrew remote crew: the two roles a
58
+ * task carries and the log group it writes to.
59
+ *
60
+ * One per crew, alongside the shared {@link FargateCrewBase}. Deleting this
61
+ * removes exactly one crew's identity and logs and leaves the cluster and its
62
+ * siblings untouched. Port of the upstream `kirocrew-fargate-crew` template.
63
+ *
64
+ * Security invariants preserved from upstream:
65
+ * - The **task role** (the running container's identity, and the blast radius
66
+ * one agent turn reaches) is created with NO policies and MUST NEVER be
67
+ * granted `secretsmanager:GetSecretValue` — the model credential is already
68
+ * in the container env, so the grant buys nothing while letting one turn read
69
+ * every crew's secret.
70
+ * - The **execution role** reads secrets scoped to `kirocrew/crew/<crew>/*`
71
+ * only, with individually-listed actions (no prefix wildcards).
72
+ * - Both assume-role policies carry an `aws:SourceAccount` condition so the
73
+ * roles are not assumable on behalf of an unrelated stack's task.
74
+ */
75
+ export declare class FargateCrew extends Construct {
76
+ /** Role ECS assumes BEFORE the container starts (secret fetch + log stream). */
77
+ readonly executionRole: iam.Role;
78
+ /** Identity the RUNNING container carries. Created with no policies. */
79
+ readonly taskRole: iam.Role;
80
+ /** The crew's log group (`/kirocrew/crew/<crew>`). */
81
+ readonly logGroup: logs.LogGroup;
82
+ /** The crew this construct scaffolds. */
83
+ readonly crew: string;
84
+ /** The one secret ARN pattern the execution role may read. */
85
+ readonly secretArnPattern: string;
86
+ constructor(scope: Construct, id: string, props: FargateCrewProps);
87
+ /** Namespace a crew secret must be created under for the exec role to read it. */
88
+ get secretNamePrefix(): string;
89
+ }
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.FargateCrew = void 0;
37
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
38
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
39
+ const iam = __importStar(require("aws-cdk-lib/aws-iam"));
40
+ const logs = __importStar(require("aws-cdk-lib/aws-logs"));
41
+ const constructs_1 = require("constructs");
42
+ // Mirrors _CREW_RE in the upstream cloud/fargate/identity.py exactly. A
43
+ // trailing hyphen would make the derived role end in "--exec"; a leading one is
44
+ // not a legal start for the derived resource names.
45
+ const CREW_RE = /^[a-z0-9]([a-z0-9-]{0,30}[a-z0-9])?$/;
46
+ // Matches the upstream template's PermissionsBoundaryArn AllowedPattern.
47
+ const BOUNDARY_RE = /^arn:aws(-[a-z0-9]+)*:iam::[0-9]{12}:policy\/kirocrew-crew-boundary$/;
48
+ const ECR_REPO_RE = /^arn:aws(-[a-z0-9]+)*:ecr:[a-z0-9-]{1,32}:[0-9]{12}:repository\/[a-zA-Z0-9._/-]+$/;
49
+ /** CloudWatch Logs retention values the upstream template permits. */
50
+ const ALLOWED_RETENTION_DAYS = [1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365];
51
+ /**
52
+ * Per-crew Fargate scaffolding for ONE KiroCrew remote crew: the two roles a
53
+ * task carries and the log group it writes to.
54
+ *
55
+ * One per crew, alongside the shared {@link FargateCrewBase}. Deleting this
56
+ * removes exactly one crew's identity and logs and leaves the cluster and its
57
+ * siblings untouched. Port of the upstream `kirocrew-fargate-crew` template.
58
+ *
59
+ * Security invariants preserved from upstream:
60
+ * - The **task role** (the running container's identity, and the blast radius
61
+ * one agent turn reaches) is created with NO policies and MUST NEVER be
62
+ * granted `secretsmanager:GetSecretValue` — the model credential is already
63
+ * in the container env, so the grant buys nothing while letting one turn read
64
+ * every crew's secret.
65
+ * - The **execution role** reads secrets scoped to `kirocrew/crew/<crew>/*`
66
+ * only, with individually-listed actions (no prefix wildcards).
67
+ * - Both assume-role policies carry an `aws:SourceAccount` condition so the
68
+ * roles are not assumable on behalf of an unrelated stack's task.
69
+ */
70
+ class FargateCrew extends constructs_1.Construct {
71
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@raindancers/raindancers-crew.FargateCrew", version: "0.0.0" };
72
+ /** Role ECS assumes BEFORE the container starts (secret fetch + log stream). */
73
+ executionRole;
74
+ /** Identity the RUNNING container carries. Created with no policies. */
75
+ taskRole;
76
+ /** The crew's log group (`/kirocrew/crew/<crew>`). */
77
+ logGroup;
78
+ /** The crew this construct scaffolds. */
79
+ crew;
80
+ /** The one secret ARN pattern the execution role may read. */
81
+ secretArnPattern;
82
+ constructor(scope, id, props) {
83
+ super(scope, id);
84
+ const crew = props.crew;
85
+ if (!CREW_RE.test(crew)) {
86
+ throw new Error('crew must be 1-32 chars, lower-case alphanumeric with inner hyphens ' +
87
+ `(never leading/trailing); got '${crew}'`);
88
+ }
89
+ const retention = props.logRetentionDays ?? 30;
90
+ if (!ALLOWED_RETENTION_DAYS.includes(retention)) {
91
+ throw new Error(`logRetentionDays must be one of ${ALLOWED_RETENTION_DAYS.join(', ')}`);
92
+ }
93
+ if (props.permissionsBoundaryArn && !BOUNDARY_RE.test(props.permissionsBoundaryArn)) {
94
+ throw new Error('permissionsBoundaryArn must be a kirocrew-crew-boundary policy ARN');
95
+ }
96
+ if (props.ecrRepositoryArn && !ECR_REPO_RE.test(props.ecrRepositoryArn)) {
97
+ throw new Error('ecrRepositoryArn must be a valid ECR repository ARN');
98
+ }
99
+ this.crew = crew;
100
+ const boundary = props.permissionsBoundaryArn
101
+ ? iam.ManagedPolicy.fromManagedPolicyArn(this, 'Boundary', props.permissionsBoundaryArn)
102
+ : undefined;
103
+ // Log group. Name is FIXED (logConfiguration is one of the four fields
104
+ // RunTask cannot override), derived as /kirocrew/crew/<crew>.
105
+ this.logGroup = new logs.LogGroup(this, 'LogGroup', {
106
+ logGroupName: `/kirocrew/crew/${crew}`,
107
+ retention: retentionToEnum(retention),
108
+ });
109
+ const secretArnPattern = `arn:${aws_cdk_lib_1.Aws.PARTITION}:secretsmanager:${aws_cdk_lib_1.Aws.REGION}:${aws_cdk_lib_1.Aws.ACCOUNT_ID}:secret:kirocrew/crew/${crew}/*`;
110
+ this.secretArnPattern = secretArnPattern;
111
+ const logGroupArn = `arn:${aws_cdk_lib_1.Aws.PARTITION}:logs:${aws_cdk_lib_1.Aws.REGION}:${aws_cdk_lib_1.Aws.ACCOUNT_ID}:log-group:/kirocrew/crew/${crew}:*`;
112
+ const assumedBy = new iam.ServicePrincipal('ecs-tasks.amazonaws.com', {
113
+ conditions: {
114
+ // Without this the role is assumable on behalf of any task in the
115
+ // account, including one an unrelated stack registered.
116
+ StringEquals: { 'aws:SourceAccount': aws_cdk_lib_1.Aws.ACCOUNT_ID },
117
+ },
118
+ });
119
+ // Execution role: what ECS assumes BEFORE the container starts, to fetch
120
+ // secrets and open the log stream. The container never holds this role,
121
+ // which is why the secret read lives here and not on the task role.
122
+ this.executionRole = new iam.Role(this, 'ExecutionRole', {
123
+ roleName: `kirocrew-crew-${crew}-exec`,
124
+ assumedBy,
125
+ permissionsBoundary: boundary,
126
+ });
127
+ this.executionRole.addToPolicy(new iam.PolicyStatement({
128
+ // Scoped to THIS crew's secret namespace. The trailing wildcard covers
129
+ // only the six-char suffix Secrets Manager appends; it does not widen
130
+ // the crew segment, so this role cannot read a sibling's secret.
131
+ actions: ['secretsmanager:GetSecretValue'],
132
+ resources: [secretArnPattern],
133
+ }));
134
+ this.executionRole.addToPolicy(new iam.PolicyStatement({
135
+ // CreateLogGroup is absent on purpose: the group is created by this
136
+ // construct, so a task that could create one could write outside the
137
+ // namespace it is retained and deleted under.
138
+ actions: ['logs:CreateLogStream', 'logs:PutLogEvents'],
139
+ resources: [logGroupArn],
140
+ }));
141
+ if (props.ecrRepositoryArn) {
142
+ // GetAuthorizationToken is account-wide by the service's own design (it
143
+ // names no repository); the layer/image reads are scoped to the repo.
144
+ this.executionRole.addToPolicy(new iam.PolicyStatement({
145
+ actions: ['ecr:GetAuthorizationToken'],
146
+ resources: ['*'],
147
+ }));
148
+ this.executionRole.addToPolicy(new iam.PolicyStatement({
149
+ actions: [
150
+ 'ecr:BatchCheckLayerAvailability',
151
+ 'ecr:BatchGetImage',
152
+ 'ecr:GetDownloadUrlForLayer',
153
+ ],
154
+ resources: [props.ecrRepositoryArn],
155
+ }));
156
+ }
157
+ // Task role: the identity the RUNNING container carries. Created with NO
158
+ // policies at all — the intended starting state. It must NEVER be granted
159
+ // secretsmanager:GetSecretValue (see class docstring).
160
+ this.taskRole = new iam.Role(this, 'TaskRole', {
161
+ roleName: `kirocrew-crew-${crew}-task`,
162
+ assumedBy,
163
+ permissionsBoundary: boundary,
164
+ });
165
+ // Off-box backup: the RUNNING container pushes snapshots, so the grant goes
166
+ // on the task role. It stays scoped to the backup bucket + its KMS key —
167
+ // this does not reintroduce any secret-read the task role is denied.
168
+ if (props.backupBucket) {
169
+ props.backupBucket.grantWrite(this.taskRole);
170
+ props.backupBucket.grantRead(this.taskRole);
171
+ }
172
+ for (const taggable of [this.logGroup, this.executionRole, this.taskRole]) {
173
+ aws_cdk_lib_1.Tags.of(taggable).add('kirocrew:managed', 'true');
174
+ aws_cdk_lib_1.Tags.of(taggable).add('kirocrew:crew', crew);
175
+ }
176
+ }
177
+ /** Namespace a crew secret must be created under for the exec role to read it. */
178
+ get secretNamePrefix() {
179
+ return `kirocrew/crew/${this.crew}/`;
180
+ }
181
+ }
182
+ exports.FargateCrew = FargateCrew;
183
+ function retentionToEnum(days) {
184
+ const map = {
185
+ 1: logs.RetentionDays.ONE_DAY,
186
+ 3: logs.RetentionDays.THREE_DAYS,
187
+ 5: logs.RetentionDays.FIVE_DAYS,
188
+ 7: logs.RetentionDays.ONE_WEEK,
189
+ 14: logs.RetentionDays.TWO_WEEKS,
190
+ 30: logs.RetentionDays.ONE_MONTH,
191
+ 60: logs.RetentionDays.TWO_MONTHS,
192
+ 90: logs.RetentionDays.THREE_MONTHS,
193
+ 120: logs.RetentionDays.FOUR_MONTHS,
194
+ 150: logs.RetentionDays.FIVE_MONTHS,
195
+ 180: logs.RetentionDays.SIX_MONTHS,
196
+ 365: logs.RetentionDays.ONE_YEAR,
197
+ };
198
+ return map[days];
199
+ }
200
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFyZ2F0ZS1jcmV3LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ZhcmdhdGUtY3Jldy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNkNBQXdDO0FBQ3hDLHlEQUEyQztBQUMzQywyREFBNkM7QUFDN0MsMkNBQXVDO0FBR3ZDLHdFQUF3RTtBQUN4RSxnRkFBZ0Y7QUFDaEYsb0RBQW9EO0FBQ3BELE1BQU0sT0FBTyxHQUFHLHNDQUFzQyxDQUFDO0FBQ3ZELHlFQUF5RTtBQUN6RSxNQUFNLFdBQVcsR0FDZixzRUFBc0UsQ0FBQztBQUN6RSxNQUFNLFdBQVcsR0FDZixtRkFBbUYsQ0FBQztBQUV0RixzRUFBc0U7QUFDdEUsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUEwRGhGOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFDSCxNQUFhLFdBQVksU0FBUSxzQkFBUzs7SUFDeEMsZ0ZBQWdGO0lBQ2hFLGFBQWEsQ0FBVztJQUN4Qyx3RUFBd0U7SUFDeEQsUUFBUSxDQUFXO0lBQ25DLHNEQUFzRDtJQUN0QyxRQUFRLENBQWdCO0lBQ3hDLHlDQUF5QztJQUN6QixJQUFJLENBQVM7SUFDN0IsOERBQThEO0lBQzlDLGdCQUFnQixDQUFTO0lBRXpDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBdUI7UUFDL0QsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7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RSxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVU7UUFDbEMsR0FBRyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUTtLQUNqQyxDQUFDO0lBQ0YsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEF3cywgVGFncyB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGlhbSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCAqIGFzIGxvZ3MgZnJvbSAnYXdzLWNkay1saWIvYXdzLWxvZ3MnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBJQ3Jld0JhY2t1cEJ1Y2tldCB9IGZyb20gJy4vcmVtb3RlLWNyZXctaW5zdGFuY2UtcHJvcHMnO1xuXG4vLyBNaXJyb3JzIF9DUkVXX1JFIGluIHRoZSB1cHN0cmVhbSBjbG91ZC9mYXJnYXRlL2lkZW50aXR5LnB5IGV4YWN0bHkuIEFcbi8vIHRyYWlsaW5nIGh5cGhlbiB3b3VsZCBtYWtlIHRoZSBkZXJpdmVkIHJvbGUgZW5kIGluIFwiLS1leGVjXCI7IGEgbGVhZGluZyBvbmUgaXNcbi8vIG5vdCBhIGxlZ2FsIHN0YXJ0IGZvciB0aGUgZGVyaXZlZCByZXNvdXJjZSBuYW1lcy5cbmNvbnN0IENSRVdfUkUgPSAvXlthLXowLTldKFthLXowLTktXXswLDMwfVthLXowLTldKT8kLztcbi8vIE1hdGNoZXMgdGhlIHVwc3RyZWFtIHRlbXBsYXRlJ3MgUGVybWlzc2lvbnNCb3VuZGFyeUFybiBBbGxvd2VkUGF0dGVybi5cbmNvbnN0IEJPVU5EQVJZX1JFID1cbiAgL15hcm46YXdzKC1bYS16MC05XSspKjppYW06OlswLTldezEyfTpwb2xpY3lcXC9raXJvY3Jldy1jcmV3LWJvdW5kYXJ5JC87XG5jb25zdCBFQ1JfUkVQT19SRSA9XG4gIC9eYXJuOmF3cygtW2EtejAtOV0rKSo6ZWNyOlthLXowLTktXXsxLDMyfTpbMC05XXsxMn06cmVwb3NpdG9yeVxcL1thLXpBLVowLTkuXy8tXSskLztcblxuLyoqIENsb3VkV2F0Y2ggTG9ncyByZXRlbnRpb24gdmFsdWVzIHRoZSB1cHN0cmVhbSB0ZW1wbGF0ZSBwZXJtaXRzLiAqL1xuY29uc3QgQUxMT1dFRF9SRVRFTlRJT05fREFZUyA9IFsxLCAzLCA1LCA3LCAxNCwgMzAsIDYwLCA5MCwgMTIwLCAxNTAsIDE4MCwgMzY1XTtcblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciB7QGxpbmsgRmFyZ2F0ZUNyZXd9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEZhcmdhdGVDcmV3UHJvcHMge1xuICAvKipcbiAgICogQ3JldyBuYW1lOiAx4oCTMzIgY2hhcnMsIGxvd2VyLWNhc2UgYWxwaGFudW1lcmljIHdpdGggaW5uZXIgaHlwaGVucywgbmV2ZXJcbiAgICogbGVhZGluZyBvciB0cmFpbGluZy4gRXZlcnkgcmVzb3VyY2UgbmFtZSBpcyBERVJJVkVEIGZyb20gaXQg4oCUIHRoZSB0YXNrXG4gICAqIGRlZmluaXRpb24gcmVidWlsZHMgdGhlIHJvbGUgQVJOcyBhbmQgbG9nLWdyb3VwIG5hbWUgZnJvbSB0aGUgY3JldyBuYW1lXG4gICAqIGFuZCByZWZ1c2VzIGEgZG9jdW1lbnQgd2hvc2UgQVJOcyBkaXNhZ3JlZSwgc28gYSByZW5hbWUgaGVyZSBpcyBhIGxhdW5jaFxuICAgKiByZWZ1c2FsLCBub3QgYSBzaWxlbnQgbWlzbWF0Y2guXG4gICAqL1xuICByZWFkb25seSBjcmV3OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIERheXMgYSBjcmV3J3MgdGFzayBsb2dzIGFyZSBrZXB0IGJlZm9yZSBDbG91ZFdhdGNoIGV4cGlyZXMgdGhlbS4gTXVzdCBiZVxuICAgKiBvbmUgb2YgdGhlIENsb3VkV2F0Y2ggcmV0ZW50aW9uIHZhbHVlcy5cbiAgICpcbiAgICogQGRlZmF1bHQgMzBcbiAgICovXG4gIHJlYWRvbmx5IGxvZ1JldGVudGlvbkRheXM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEFSTiBvZiB0aGUgcHJlLWNyZWF0ZWQgc2hhcmVkIGNyZXcgcGVybWlzc2lvbnMgYm91bmRhcnlcbiAgICogKGBhcm46YXdzOmlhbTo6PGFjY291bnQ+OnBvbGljeS9raXJvY3Jldy1jcmV3LWJvdW5kYXJ5YCkuXG4gICAqXG4gICAqIE9wdGlvbmFsIGJ5IGRlc2lnbjogdGhpcyBpcyBhIERFQ0xBUkVEIGRlZ3JhZGVkIG1vZGUuIFVubGlrZSB0aGUgRUMyIGxhbmVcbiAgICogKHdob3NlIGJvdW5kYXJ5IGlzIGNyZWF0ZWQgb25jZSBieSBsYXVuY2hlciBjb2RlKSwgbm8gY3JlYXRvciBleGlzdHMgZm9yXG4gICAqIHRoZSBjcmV3IGJvdW5kYXJ5IHlldCwgc28gcmF0aGVyIHRoYW4gcmVmZXJlbmNlIGEgcG9saWN5IG5vdGhpbmcgY3JlYXRlc1xuICAgKiB0aGlzIGlzIG9taXR0ZWQgdW50aWwgdGhhdCBjcmVhdG9yIGxhbmRzLiBXaGVuIHNldCwgaXQgY2FwcyB3aGF0IHRoZXNlXG4gICAqIHJvbGVzIGNhbiBldmVyIGRvIHJlZ2FyZGxlc3Mgb2YgYXR0YWNoZWQgcG9saWNpZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gYm91bmRhcnkgKGRlY2xhcmVkIGRlZ3JhZGVkIG1vZGUpXG4gICAqL1xuICByZWFkb25seSBwZXJtaXNzaW9uc0JvdW5kYXJ5QXJuPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBUk4gb2YgdGhlIHByaXZhdGUgRUNSIHJlcG9zaXRvcnkgaG9sZGluZyB0aGUgY3JldyBpbWFnZS4gTGVhdmUgdW5zZXQgd2hlblxuICAgKiB0aGUgaW1hZ2UgaXMgcHVsbGVkIGZyb20gYSBwdWJsaWMgcmVnaXN0cnkgKHRoZSBkZWNpZGVkIGRlbGl2ZXJ5LCBFQ1JcbiAgICogUHVibGljKSwgd2hpY2ggbmVlZHMgbm8gZXhlY3V0aW9uLXJvbGUgcHVsbCBncmFudC4gV2hlbiBzZXQsIHRoZSBwdWxsIGdyYW50XG4gICAqIGlzIHNjb3BlZCB0byB0aGlzIG9uZSByZXBvc2l0b3J5LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHB1YmxpYyByZWdpc3RyeTsgbm8gcHVsbCBncmFudFxuICAgKi9cbiAgcmVhZG9ubHkgZWNyUmVwb3NpdG9yeUFybj86IHN0cmluZztcblxuICAvKipcbiAgICogQW4gUzMgYmFja3VwIGJ1Y2tldCB0byBncmFudCB0aGUgVEFTSyByb2xlIHdyaXRlIGFjY2VzcyB0bywgc28gdGhlIHJ1bm5pbmdcbiAgICogY3JldyBjb250YWluZXIgY2FuIHB1c2ggYGtpcm9jcmV3IHNuYXBzaG90YCBidW5kbGVzIG9mZi1ib3ggb24gaXRzIG93blxuICAgKiBzY2hlZHVsZS4gVGhlIHRhc2sgcm9sZSAobm90IHRoZSBleGVjdXRpb24gcm9sZSkgZ2V0cyB0aGlzLCBiZWNhdXNlIHRoZVxuICAgKiBwdXNoIHJ1bnMgaW5zaWRlIHRoZSBjb250YWluZXIuIE9taXQgdG8gZGlzYWJsZSBvZmYtYm94IGJhY2t1cC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBvZmYtYm94IGJhY2t1cCBncmFudFxuICAgKi9cbiAgcmVhZG9ubHkgYmFja3VwQnVja2V0PzogSUNyZXdCYWNrdXBCdWNrZXQ7XG59XG5cbi8qKlxuICogUGVyLWNyZXcgRmFyZ2F0ZSBzY2FmZm9sZGluZyBmb3IgT05FIEtpcm9DcmV3IHJlbW90ZSBjcmV3OiB0aGUgdHdvIHJvbGVzIGFcbiAqIHRhc2sgY2FycmllcyBhbmQgdGhlIGxvZyBncm91cCBpdCB3cml0ZXMgdG8uXG4gKlxuICogT25lIHBlciBjcmV3LCBhbG9uZ3NpZGUgdGhlIHNoYXJlZCB7QGxpbmsgRmFyZ2F0ZUNyZXdCYXNlfS4gRGVsZXRpbmcgdGhpc1xuICogcmVtb3ZlcyBleGFjdGx5IG9uZSBjcmV3J3MgaWRlbnRpdHkgYW5kIGxvZ3MgYW5kIGxlYXZlcyB0aGUgY2x1c3RlciBhbmQgaXRzXG4gKiBzaWJsaW5ncyB1bnRvdWNoZWQuIFBvcnQgb2YgdGhlIHVwc3RyZWFtIGBraXJvY3Jldy1mYXJnYXRlLWNyZXdgIHRlbXBsYXRlLlxuICpcbiAqIFNlY3VyaXR5IGludmFyaWFudHMgcHJlc2VydmVkIGZyb20gdXBzdHJlYW06XG4gKiAtIFRoZSAqKnRhc2sgcm9sZSoqICh0aGUgcnVubmluZyBjb250YWluZXIncyBpZGVudGl0eSwgYW5kIHRoZSBibGFzdCByYWRpdXNcbiAqICAgb25lIGFnZW50IHR1cm4gcmVhY2hlcykgaXMgY3JlYXRlZCB3aXRoIE5PIHBvbGljaWVzIGFuZCBNVVNUIE5FVkVSIGJlXG4gKiAgIGdyYW50ZWQgYHNlY3JldHNtYW5hZ2VyOkdldFNlY3JldFZhbHVlYCDigJQgdGhlIG1vZGVsIGNyZWRlbnRpYWwgaXMgYWxyZWFkeVxuICogICBpbiB0aGUgY29udGFpbmVyIGVudiwgc28gdGhlIGdyYW50IGJ1eXMgbm90aGluZyB3aGlsZSBsZXR0aW5nIG9uZSB0dXJuIHJlYWRcbiAqICAgZXZlcnkgY3JldydzIHNlY3JldC5cbiAqIC0gVGhlICoqZXhlY3V0aW9uIHJvbGUqKiByZWFkcyBzZWNyZXRzIHNjb3BlZCB0byBga2lyb2NyZXcvY3Jldy88Y3Jldz4vKmBcbiAqICAgb25seSwgd2l0aCBpbmRpdmlkdWFsbHktbGlzdGVkIGFjdGlvbnMgKG5vIHByZWZpeCB3aWxkY2FyZHMpLlxuICogLSBCb3RoIGFzc3VtZS1yb2xlIHBvbGljaWVzIGNhcnJ5IGFuIGBhd3M6U291cmNlQWNjb3VudGAgY29uZGl0aW9uIHNvIHRoZVxuICogICByb2xlcyBhcmUgbm90IGFzc3VtYWJsZSBvbiBiZWhhbGYgb2YgYW4gdW5yZWxhdGVkIHN0YWNrJ3MgdGFzay5cbiAqL1xuZXhwb3J0IGNsYXNzIEZhcmdhdGVDcmV3IGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgLyoqIFJvbGUgRUNTIGFzc3VtZXMgQkVGT1JFIHRoZSBjb250YWluZXIgc3RhcnRzIChzZWNyZXQgZmV0Y2ggKyBsb2cgc3RyZWFtKS4gKi9cbiAgcHVibGljIHJlYWRvbmx5IGV4ZWN1dGlvblJvbGU6IGlhbS5Sb2xlO1xuICAvKiogSWRlbnRpdHkgdGhlIFJVTk5JTkcgY29udGFpbmVyIGNhcnJpZXMuIENyZWF0ZWQgd2l0aCBubyBwb2xpY2llcy4gKi9cbiAgcHVibGljIHJlYWRvbmx5IHRhc2tSb2xlOiBpYW0uUm9sZTtcbiAgLyoqIFRoZSBjcmV3J3MgbG9nIGdyb3VwIChgL2tpcm9jcmV3L2NyZXcvPGNyZXc+YCkuICovXG4gIHB1YmxpYyByZWFkb25seSBsb2dHcm91cDogbG9ncy5Mb2dHcm91cDtcbiAgLyoqIFRoZSBjcmV3IHRoaXMgY29uc3RydWN0IHNjYWZmb2xkcy4gKi9cbiAgcHVibGljIHJlYWRvbmx5IGNyZXc6IHN0cmluZztcbiAgLyoqIFRoZSBvbmUgc2VjcmV0IEFSTiBwYXR0ZXJuIHRoZSBleGVjdXRpb24gcm9sZSBtYXkgcmVhZC4gKi9cbiAgcHVibGljIHJlYWRvbmx5IHNlY3JldEFyblBhdHRlcm46IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogRmFyZ2F0ZUNyZXdQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICBjb25zdCBjcmV3ID0gcHJvcHMuY3JldztcbiAgICBpZiAoIUNSRVdfUkUudGVzdChjcmV3KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnY3JldyBtdXN0IGJlIDEtMzIgY2hhcnMsIGxvd2VyLWNhc2UgYWxwaGFudW1lcmljIHdpdGggaW5uZXIgaHlwaGVucyAnICtcbiAgICAgICAgICBgKG5ldmVyIGxlYWRpbmcvdHJhaWxpbmcpOyBnb3QgJyR7Y3Jld30nYCxcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IHJldGVudGlvbiA9IHByb3BzLmxvZ1JldGVudGlvbkRheXMgPz8gMzA7XG4gICAgaWYgKCFBTExPV0VEX1JFVEVOVElPTl9EQVlTLmluY2x1ZGVzKHJldGVudGlvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYGxvZ1JldGVudGlvbkRheXMgbXVzdCBiZSBvbmUgb2YgJHtBTExPV0VEX1JFVEVOVElPTl9EQVlTLmpvaW4oJywgJyl9YCxcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChwcm9wcy5wZXJtaXNzaW9uc0JvdW5kYXJ5QXJuICYmICFCT1VOREFSWV9SRS50ZXN0KHByb3BzLnBlcm1pc3Npb25zQm91bmRhcnlBcm4pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdwZXJtaXNzaW9uc0JvdW5kYXJ5QXJuIG11c3QgYmUgYSBraXJvY3Jldy1jcmV3LWJvdW5kYXJ5IHBvbGljeSBBUk4nLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHByb3BzLmVjclJlcG9zaXRvcnlBcm4gJiYgIUVDUl9SRVBPX1JFLnRlc3QocHJvcHMuZWNyUmVwb3NpdG9yeUFybikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZWNyUmVwb3NpdG9yeUFybiBtdXN0IGJlIGEgdmFsaWQgRUNSIHJlcG9zaXRvcnkgQVJOJyk7XG4gICAgfVxuICAgIHRoaXMuY3JldyA9IGNyZXc7XG5cbiAgICBjb25zdCBib3VuZGFyeSA9IHByb3BzLnBlcm1pc3Npb25zQm91bmRhcnlBcm5cbiAgICAgID8gaWFtLk1hbmFnZWRQb2xpY3kuZnJvbU1hbmFnZWRQb2xpY3lBcm4odGhpcywgJ0JvdW5kYXJ5JywgcHJvcHMucGVybWlzc2lvbnNCb3VuZGFyeUFybilcbiAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgLy8gTG9nIGdyb3VwLiBOYW1lIGlzIEZJWEVEIChsb2dDb25maWd1cmF0aW9uIGlzIG9uZSBvZiB0aGUgZm91ciBmaWVsZHNcbiAgICAvLyBSdW5UYXNrIGNhbm5vdCBvdmVycmlkZSksIGRlcml2ZWQgYXMgL2tpcm9jcmV3L2NyZXcvPGNyZXc+LlxuICAgIHRoaXMubG9nR3JvdXAgPSBuZXcgbG9ncy5Mb2dHcm91cCh0aGlzLCAnTG9nR3JvdXAnLCB7XG4gICAgICBsb2dHcm91cE5hbWU6IGAva2lyb2NyZXcvY3Jldy8ke2NyZXd9YCxcbiAgICAgIHJldGVudGlvbjogcmV0ZW50aW9uVG9FbnVtKHJldGVudGlvbiksXG4gICAgfSk7XG5cbiAgICBjb25zdCBzZWNyZXRBcm5QYXR0ZXJuID0gYGFybjoke0F3cy5QQVJUSVRJT059OnNlY3JldHNtYW5hZ2VyOiR7QXdzLlJFR0lPTn06JHtBd3MuQUNDT1VOVF9JRH06c2VjcmV0Omtpcm9jcmV3L2NyZXcvJHtjcmV3fS8qYDtcbiAgICB0aGlzLnNlY3JldEFyblBhdHRlcm4gPSBzZWNyZXRBcm5QYXR0ZXJuO1xuICAgIGNvbnN0IGxvZ0dyb3VwQXJuID0gYGFybjoke0F3cy5QQVJUSVRJT059OmxvZ3M6JHtBd3MuUkVHSU9OfToke0F3cy5BQ0NPVU5UX0lEfTpsb2ctZ3JvdXA6L2tpcm9jcmV3L2NyZXcvJHtjcmV3fToqYDtcblxuICAgIGNvbnN0IGFzc3VtZWRCeSA9IG5ldyBpYW0uU2VydmljZVByaW5jaXBhbCgnZWNzLXRhc2tzLmFtYXpvbmF3cy5jb20nLCB7XG4gICAgICBjb25kaXRpb25zOiB7XG4gICAgICAgIC8vIFdpdGhvdXQgdGhpcyB0aGUgcm9sZSBpcyBhc3N1bWFibGUgb24gYmVoYWxmIG9mIGFueSB0YXNrIGluIHRoZVxuICAgICAgICAvLyBhY2NvdW50LCBpbmNsdWRpbmcgb25lIGFuIHVucmVsYXRlZCBzdGFjayByZWdpc3RlcmVkLlxuICAgICAgICBTdHJpbmdFcXVhbHM6IHsgJ2F3czpTb3VyY2VBY2NvdW50JzogQXdzLkFDQ09VTlRfSUQgfSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyBFeGVjdXRpb24gcm9sZTogd2hhdCBFQ1MgYXNzdW1lcyBCRUZPUkUgdGhlIGNvbnRhaW5lciBzdGFydHMsIHRvIGZldGNoXG4gICAgLy8gc2VjcmV0cyBhbmQgb3BlbiB0aGUgbG9nIHN0cmVhbS4gVGhlIGNvbnRhaW5lciBuZXZlciBob2xkcyB0aGlzIHJvbGUsXG4gICAgLy8gd2hpY2ggaXMgd2h5IHRoZSBzZWNyZXQgcmVhZCBsaXZlcyBoZXJlIGFuZCBub3Qgb24gdGhlIHRhc2sgcm9sZS5cbiAgICB0aGlzLmV4ZWN1dGlvblJvbGUgPSBuZXcgaWFtLlJvbGUodGhpcywgJ0V4ZWN1dGlvblJvbGUnLCB7XG4gICAgICByb2xlTmFtZTogYGtpcm9jcmV3LWNyZXctJHtjcmV3fS1leGVjYCxcbiAgICAgIGFzc3VtZWRCeSxcbiAgICAgIHBlcm1pc3Npb25zQm91bmRhcnk6IGJvdW5kYXJ5LFxuICAgIH0pO1xuICAgIHRoaXMuZXhlY3V0aW9uUm9sZS5hZGRUb1BvbGljeShcbiAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgLy8gU2NvcGVkIHRvIFRISVMgY3JldydzIHNlY3JldCBuYW1lc3BhY2UuIFRoZSB0cmFpbGluZyB3aWxkY2FyZCBjb3ZlcnNcbiAgICAgICAgLy8gb25seSB0aGUgc2l4LWNoYXIgc3VmZml4IFNlY3JldHMgTWFuYWdlciBhcHBlbmRzOyBpdCBkb2VzIG5vdCB3aWRlblxuICAgICAgICAvLyB0aGUgY3JldyBzZWdtZW50LCBzbyB0aGlzIHJvbGUgY2Fubm90IHJlYWQgYSBzaWJsaW5nJ3Mgc2VjcmV0LlxuICAgICAgICBhY3Rpb25zOiBbJ3NlY3JldHNtYW5hZ2VyOkdldFNlY3JldFZhbHVlJ10sXG4gICAgICAgIHJlc291cmNlczogW3NlY3JldEFyblBhdHRlcm5dLFxuICAgICAgfSksXG4gICAgKTtcbiAgICB0aGlzLmV4ZWN1dGlvblJvbGUuYWRkVG9Qb2xpY3koXG4gICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIC8vIENyZWF0ZUxvZ0dyb3VwIGlzIGFic2VudCBvbiBwdXJwb3NlOiB0aGUgZ3JvdXAgaXMgY3JlYXRlZCBieSB0aGlzXG4gICAgICAgIC8vIGNvbnN0cnVjdCwgc28gYSB0YXNrIHRoYXQgY291bGQgY3JlYXRlIG9uZSBjb3VsZCB3cml0ZSBvdXRzaWRlIHRoZVxuICAgICAgICAvLyBuYW1lc3BhY2UgaXQgaXMgcmV0YWluZWQgYW5kIGRlbGV0ZWQgdW5kZXIuXG4gICAgICAgIGFjdGlvbnM6IFsnbG9nczpDcmVhdGVMb2dTdHJlYW0nLCAnbG9nczpQdXRMb2dFdmVudHMnXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbbG9nR3JvdXBBcm5dLFxuICAgICAgfSksXG4gICAgKTtcbiAgICBpZiAocHJvcHMuZWNyUmVwb3NpdG9yeUFybikge1xuICAgICAgLy8gR2V0QXV0aG9yaXphdGlvblRva2VuIGlzIGFjY291bnQtd2lkZSBieSB0aGUgc2VydmljZSdzIG93biBkZXNpZ24gKGl0XG4gICAgICAvLyBuYW1lcyBubyByZXBvc2l0b3J5KTsgdGhlIGxheWVyL2ltYWdlIHJlYWRzIGFyZSBzY29wZWQgdG8gdGhlIHJlcG8uXG4gICAgICB0aGlzLmV4ZWN1dGlvblJvbGUuYWRkVG9Qb2xpY3koXG4gICAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBhY3Rpb25zOiBbJ2VjcjpHZXRBdXRob3JpemF0aW9uVG9rZW4nXSxcbiAgICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgICB0aGlzLmV4ZWN1dGlvblJvbGUuYWRkVG9Qb2xpY3koXG4gICAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgICAnZWNyOkJhdGNoQ2hlY2tMYXllckF2YWlsYWJpbGl0eScsXG4gICAgICAgICAgICAnZWNyOkJhdGNoR2V0SW1hZ2UnLFxuICAgICAgICAgICAgJ2VjcjpHZXREb3dubG9hZFVybEZvckxheWVyJyxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHJlc291cmNlczogW3Byb3BzLmVjclJlcG9zaXRvcnlBcm5dLFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gVGFzayByb2xlOiB0aGUgaWRlbnRpdHkgdGhlIFJVTk5JTkcgY29udGFpbmVyIGNhcnJpZXMuIENyZWF0ZWQgd2l0aCBOT1xuICAgIC8vIHBvbGljaWVzIGF0IGFsbCDigJQgdGhlIGludGVuZGVkIHN0YXJ0aW5nIHN0YXRlLiBJdCBtdXN0IE5FVkVSIGJlIGdyYW50ZWRcbiAgICAvLyBzZWNyZXRzbWFuYWdlcjpHZXRTZWNyZXRWYWx1ZSAoc2VlIGNsYXNzIGRvY3N0cmluZykuXG4gICAgdGhpcy50YXNrUm9sZSA9IG5ldyBpYW0uUm9sZSh0aGlzLCAnVGFza1JvbGUnLCB7XG4gICAgICByb2xlTmFtZTogYGtpcm9jcmV3LWNyZXctJHtjcmV3fS10YXNrYCxcbiAgICAgIGFzc3VtZWRCeSxcbiAgICAgIHBlcm1pc3Npb25zQm91bmRhcnk6IGJvdW5kYXJ5LFxuICAgIH0pO1xuXG4gICAgLy8gT2ZmLWJveCBiYWNrdXA6IHRoZSBSVU5OSU5HIGNvbnRhaW5lciBwdXNoZXMgc25hcHNob3RzLCBzbyB0aGUgZ3JhbnQgZ29lc1xuICAgIC8vIG9uIHRoZSB0YXNrIHJvbGUuIEl0IHN0YXlzIHNjb3BlZCB0byB0aGUgYmFja3VwIGJ1Y2tldCArIGl0cyBLTVMga2V5IOKAlFxuICAgIC8vIHRoaXMgZG9lcyBub3QgcmVpbnRyb2R1Y2UgYW55IHNlY3JldC1yZWFkIHRoZSB0YXNrIHJvbGUgaXMgZGVuaWVkLlxuICAgIGlmIChwcm9wcy5iYWNrdXBCdWNrZXQpIHtcbiAgICAgIHByb3BzLmJhY2t1cEJ1Y2tldC5ncmFudFdyaXRlKHRoaXMudGFza1JvbGUpO1xuICAgICAgcHJvcHMuYmFja3VwQnVja2V0LmdyYW50UmVhZCh0aGlzLnRhc2tSb2xlKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHRhZ2dhYmxlIG9mIFt0aGlzLmxvZ0dyb3VwLCB0aGlzLmV4ZWN1dGlvblJvbGUsIHRoaXMudGFza1JvbGVdKSB7XG4gICAgICBUYWdzLm9mKHRhZ2dhYmxlKS5hZGQoJ2tpcm9jcmV3Om1hbmFnZWQnLCAndHJ1ZScpO1xuICAgICAgVGFncy5vZih0YWdnYWJsZSkuYWRkKCdraXJvY3JldzpjcmV3JywgY3Jldyk7XG4gICAgfVxuICB9XG5cbiAgLyoqIE5hbWVzcGFjZSBhIGNyZXcgc2VjcmV0IG11c3QgYmUgY3JlYXRlZCB1bmRlciBmb3IgdGhlIGV4ZWMgcm9sZSB0byByZWFkIGl0LiAqL1xuICBwdWJsaWMgZ2V0IHNlY3JldE5hbWVQcmVmaXgoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYGtpcm9jcmV3L2NyZXcvJHt0aGlzLmNyZXd9L2A7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmV0ZW50aW9uVG9FbnVtKGRheXM6IG51bWJlcik6IGxvZ3MuUmV0ZW50aW9uRGF5cyB7XG4gIGNvbnN0IG1hcDogUmVjb3JkPG51bWJlciwgbG9ncy5SZXRlbnRpb25EYXlzPiA9IHtcbiAgICAxOiBsb2dzLlJldGVudGlvbkRheXMuT05FX0RBWSxcbiAgICAzOiBsb2dzLlJldGVudGlvbkRheXMuVEhSRUVfREFZUyxcbiAgICA1OiBsb2dzLlJldGVudGlvbkRheXMuRklWRV9EQVlTLFxuICAgIDc6IGxvZ3MuUmV0ZW50aW9uRGF5cy5PTkVfV0VFSyxcbiAgICAxNDogbG9ncy5SZXRlbnRpb25EYXlzLlRXT19XRUVLUyxcbiAgICAzMDogbG9ncy5SZXRlbnRpb25EYXlzLk9ORV9NT05USCxcbiAgICA2MDogbG9ncy5SZXRlbnRpb25EYXlzLlRXT19NT05USFMsXG4gICAgOTA6IGxvZ3MuUmV0ZW50aW9uRGF5cy5USFJFRV9NT05USFMsXG4gICAgMTIwOiBsb2dzLlJldGVudGlvbkRheXMuRk9VUl9NT05USFMsXG4gICAgMTUwOiBsb2dzLlJldGVudGlvbkRheXMuRklWRV9NT05USFMsXG4gICAgMTgwOiBsb2dzLlJldGVudGlvbkRheXMuU0lYX01PTlRIUyxcbiAgICAzNjU6IGxvZ3MuUmV0ZW50aW9uRGF5cy5PTkVfWUVBUixcbiAgfTtcbiAgcmV0dXJuIG1hcFtkYXlzXTtcbn1cbiJdfQ==
package/lib/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from './remote-crew-instance';
2
+ export * from './remote-crew-instance-props';
3
+ export * from './fargate-crew-base';
4
+ export * from './fargate-crew';
5
+ export * from './crew-backup-bucket';
package/lib/index.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./remote-crew-instance"), exports);
18
+ __exportStar(require("./remote-crew-instance-props"), exports);
19
+ __exportStar(require("./fargate-crew-base"), exports);
20
+ __exportStar(require("./fargate-crew"), exports);
21
+ __exportStar(require("./crew-backup-bucket"), exports);
22
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHlEQUF1QztBQUN2QywrREFBNkM7QUFDN0Msc0RBQW9DO0FBQ3BDLGlEQUErQjtBQUMvQix1REFBcUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL3JlbW90ZS1jcmV3LWluc3RhbmNlJztcbmV4cG9ydCAqIGZyb20gJy4vcmVtb3RlLWNyZXctaW5zdGFuY2UtcHJvcHMnO1xuZXhwb3J0ICogZnJvbSAnLi9mYXJnYXRlLWNyZXctYmFzZSc7XG5leHBvcnQgKiBmcm9tICcuL2ZhcmdhdGUtY3Jldyc7XG5leHBvcnQgKiBmcm9tICcuL2NyZXctYmFja3VwLWJ1Y2tldCc7XG4iXX0=