@computesdk/aws-ecs 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +89 -0
- package/dist/index.d.mts +52 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.js +250 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +230 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 computesdk
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# @computesdk/aws
|
|
2
|
+
|
|
3
|
+
AWS ECS Fargate provider for ComputeSDK that enables creating and managing containerized sandboxes on AWS infrastructure.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @computesdk/aws
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Configuration
|
|
12
|
+
|
|
13
|
+
The AWS provider requires the following environment variables and AWS resources:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# AWS Credentials (or use IAM roles/profiles)
|
|
17
|
+
AWS_ACCESS_KEY_ID=your_access_key
|
|
18
|
+
AWS_SECRET_ACCESS_KEY=your_secret_key
|
|
19
|
+
AWS_REGION=us-east-1
|
|
20
|
+
|
|
21
|
+
# Required AWS Resources
|
|
22
|
+
AWS_ECS_CLUSTER=your-ecs-cluster
|
|
23
|
+
AWS_TASK_DEFINITION=your-task-definition
|
|
24
|
+
AWS_SUBNETS=subnet-xxx,subnet-yyy,subnet-zzz
|
|
25
|
+
AWS_SECURITY_GROUPS=sg-xxx
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { fargate } from '@computesdk/aws';
|
|
32
|
+
|
|
33
|
+
const provider = fargate({
|
|
34
|
+
cluster: 'my-ecs-cluster',
|
|
35
|
+
taskDefinition: 'my-task-definition',
|
|
36
|
+
subnets: ['subnet-12345', 'subnet-67890'],
|
|
37
|
+
securityGroups: ['sg-12345'],
|
|
38
|
+
region: 'us-east-1'
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Create a sandbox (ECS task)
|
|
42
|
+
const sandbox = await provider.sandbox.create({ runtime: 'node' });
|
|
43
|
+
console.log(`Created sandbox: ${sandbox.sandboxId}`);
|
|
44
|
+
|
|
45
|
+
// Get sandbox by ID
|
|
46
|
+
const retrieved = await provider.sandbox.getById(sandbox.sandboxId);
|
|
47
|
+
|
|
48
|
+
// List all running sandboxes
|
|
49
|
+
const sandboxes = await provider.sandbox.list();
|
|
50
|
+
|
|
51
|
+
// Destroy the sandbox
|
|
52
|
+
await provider.sandbox.destroy(sandbox.sandboxId);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Currently Implemented
|
|
56
|
+
|
|
57
|
+
### Sandbox Operations
|
|
58
|
+
- **create()** - Creates a new ECS Fargate task
|
|
59
|
+
- **getById()** - Retrieves a specific ECS task by ARN
|
|
60
|
+
- **list()** - Lists all running ECS tasks in the cluster
|
|
61
|
+
- **destroy()** - Stops an ECS task
|
|
62
|
+
|
|
63
|
+
### Configuration Options
|
|
64
|
+
- **cluster** - ECS cluster name or ARN (required)
|
|
65
|
+
- **taskDefinition** - Task definition family name or ARN (required)
|
|
66
|
+
- **subnets** - VPC subnet IDs for task networking (required)
|
|
67
|
+
- **securityGroups** - Security group IDs for task networking (required)
|
|
68
|
+
- **accessKeyId** - AWS access key (optional - falls back to credential chain)
|
|
69
|
+
- **secretAccessKey** - AWS secret key (optional - falls back to credential chain)
|
|
70
|
+
- **region** - AWS region (optional - defaults to AWS_REGION env var or us-east-1)
|
|
71
|
+
- **assignPublicIp** - Whether to assign public IP (optional - defaults to true)
|
|
72
|
+
- **containerName** - Container name in task definition (optional - defaults to 'sandbox')
|
|
73
|
+
|
|
74
|
+
## Prerequisites
|
|
75
|
+
|
|
76
|
+
Before using this provider, you need to set up:
|
|
77
|
+
|
|
78
|
+
1. **ECS Cluster**: A Fargate-compatible ECS cluster
|
|
79
|
+
2. **Task Definition**: A task definition with your desired container image
|
|
80
|
+
3. **VPC Networking**: Subnets and security groups for task networking
|
|
81
|
+
4. **IAM Permissions**: Appropriate permissions to create/manage ECS tasks
|
|
82
|
+
|
|
83
|
+
## Notes
|
|
84
|
+
|
|
85
|
+
- Tasks use AWS Fargate launch type (serverless containers)
|
|
86
|
+
- Container images are specified in the task definition, not at runtime
|
|
87
|
+
- The `runtime` parameter is acknowledged but actual environment depends on task definition
|
|
88
|
+
- Tasks are immediately stopped when destroyed
|
|
89
|
+
- All operations use the AWS SDK v3 for ECS
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as computesdk from 'computesdk';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* AWS ECS Fargate Provider - Factory-based Implementation
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Fargate sandbox interface
|
|
8
|
+
*/
|
|
9
|
+
interface FargateSandbox {
|
|
10
|
+
taskArn: string;
|
|
11
|
+
clusterArn: string;
|
|
12
|
+
taskId: string;
|
|
13
|
+
}
|
|
14
|
+
interface FargateConfig {
|
|
15
|
+
/** AWS Access Key ID - falls back to AWS_ACCESS_KEY_ID env var or default credential chain */
|
|
16
|
+
accessKeyId?: string;
|
|
17
|
+
/** AWS Secret Access Key - falls back to AWS_SECRET_ACCESS_KEY env var or default credential chain */
|
|
18
|
+
secretAccessKey?: string;
|
|
19
|
+
/** AWS Region - falls back to AWS_REGION env var */
|
|
20
|
+
region?: string;
|
|
21
|
+
/** ECS Cluster name or ARN */
|
|
22
|
+
cluster: string;
|
|
23
|
+
/** Task definition family name or ARN */
|
|
24
|
+
taskDefinition: string;
|
|
25
|
+
/** VPC Subnet IDs for task networking */
|
|
26
|
+
subnets: string[];
|
|
27
|
+
/** Security Group IDs for task networking */
|
|
28
|
+
securityGroups: string[];
|
|
29
|
+
/** Whether to assign a public IP (default: true) */
|
|
30
|
+
assignPublicIp?: boolean;
|
|
31
|
+
/** Container name in the task definition (default: 'sandbox') */
|
|
32
|
+
containerName?: string;
|
|
33
|
+
}
|
|
34
|
+
declare const getAndValidateCredentials: (config: FargateConfig) => {
|
|
35
|
+
region: string;
|
|
36
|
+
cluster: string;
|
|
37
|
+
taskDefinition: string;
|
|
38
|
+
subnets: string[];
|
|
39
|
+
securityGroups: string[];
|
|
40
|
+
credentials: {
|
|
41
|
+
accessKeyId: string;
|
|
42
|
+
secretAccessKey: string;
|
|
43
|
+
} | undefined;
|
|
44
|
+
assignPublicIp: boolean;
|
|
45
|
+
containerName: string;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Create an AWS ECS Fargate provider instance using the factory pattern
|
|
49
|
+
*/
|
|
50
|
+
declare const fargate: (config: FargateConfig) => computesdk.Provider<FargateSandbox, any, any>;
|
|
51
|
+
|
|
52
|
+
export { type FargateConfig, fargate, getAndValidateCredentials };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as computesdk from 'computesdk';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* AWS ECS Fargate Provider - Factory-based Implementation
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Fargate sandbox interface
|
|
8
|
+
*/
|
|
9
|
+
interface FargateSandbox {
|
|
10
|
+
taskArn: string;
|
|
11
|
+
clusterArn: string;
|
|
12
|
+
taskId: string;
|
|
13
|
+
}
|
|
14
|
+
interface FargateConfig {
|
|
15
|
+
/** AWS Access Key ID - falls back to AWS_ACCESS_KEY_ID env var or default credential chain */
|
|
16
|
+
accessKeyId?: string;
|
|
17
|
+
/** AWS Secret Access Key - falls back to AWS_SECRET_ACCESS_KEY env var or default credential chain */
|
|
18
|
+
secretAccessKey?: string;
|
|
19
|
+
/** AWS Region - falls back to AWS_REGION env var */
|
|
20
|
+
region?: string;
|
|
21
|
+
/** ECS Cluster name or ARN */
|
|
22
|
+
cluster: string;
|
|
23
|
+
/** Task definition family name or ARN */
|
|
24
|
+
taskDefinition: string;
|
|
25
|
+
/** VPC Subnet IDs for task networking */
|
|
26
|
+
subnets: string[];
|
|
27
|
+
/** Security Group IDs for task networking */
|
|
28
|
+
securityGroups: string[];
|
|
29
|
+
/** Whether to assign a public IP (default: true) */
|
|
30
|
+
assignPublicIp?: boolean;
|
|
31
|
+
/** Container name in the task definition (default: 'sandbox') */
|
|
32
|
+
containerName?: string;
|
|
33
|
+
}
|
|
34
|
+
declare const getAndValidateCredentials: (config: FargateConfig) => {
|
|
35
|
+
region: string;
|
|
36
|
+
cluster: string;
|
|
37
|
+
taskDefinition: string;
|
|
38
|
+
subnets: string[];
|
|
39
|
+
securityGroups: string[];
|
|
40
|
+
credentials: {
|
|
41
|
+
accessKeyId: string;
|
|
42
|
+
secretAccessKey: string;
|
|
43
|
+
} | undefined;
|
|
44
|
+
assignPublicIp: boolean;
|
|
45
|
+
containerName: string;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Create an AWS ECS Fargate provider instance using the factory pattern
|
|
49
|
+
*/
|
|
50
|
+
declare const fargate: (config: FargateConfig) => computesdk.Provider<FargateSandbox, any, any>;
|
|
51
|
+
|
|
52
|
+
export { type FargateConfig, fargate, getAndValidateCredentials };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
fargate: () => fargate,
|
|
24
|
+
getAndValidateCredentials: () => getAndValidateCredentials
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
var import_computesdk = require("computesdk");
|
|
28
|
+
var import_client_ecs = require("@aws-sdk/client-ecs");
|
|
29
|
+
var getAndValidateCredentials = (config) => {
|
|
30
|
+
const region = config.region || process.env?.AWS_REGION || "us-east-1";
|
|
31
|
+
const cluster = config.cluster;
|
|
32
|
+
const taskDefinition = config.taskDefinition;
|
|
33
|
+
const subnets = config.subnets;
|
|
34
|
+
const securityGroups = config.securityGroups;
|
|
35
|
+
if (!cluster) {
|
|
36
|
+
throw new Error("Missing ECS cluster. Provide cluster in config.");
|
|
37
|
+
}
|
|
38
|
+
if (!taskDefinition) {
|
|
39
|
+
throw new Error("Missing ECS task definition. Provide taskDefinition in config.");
|
|
40
|
+
}
|
|
41
|
+
if (!subnets || subnets.length === 0) {
|
|
42
|
+
throw new Error("Missing subnets. Provide at least one subnet in config.");
|
|
43
|
+
}
|
|
44
|
+
if (!securityGroups || securityGroups.length === 0) {
|
|
45
|
+
throw new Error("Missing security groups. Provide at least one security group in config.");
|
|
46
|
+
}
|
|
47
|
+
const credentials = config.accessKeyId && config.secretAccessKey ? {
|
|
48
|
+
accessKeyId: config.accessKeyId,
|
|
49
|
+
secretAccessKey: config.secretAccessKey
|
|
50
|
+
} : void 0;
|
|
51
|
+
return {
|
|
52
|
+
region,
|
|
53
|
+
cluster,
|
|
54
|
+
taskDefinition,
|
|
55
|
+
subnets,
|
|
56
|
+
securityGroups,
|
|
57
|
+
credentials,
|
|
58
|
+
assignPublicIp: config.assignPublicIp ?? true,
|
|
59
|
+
containerName: config.containerName || "sandbox"
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
var createECSClient = (config) => {
|
|
63
|
+
const { region, credentials } = getAndValidateCredentials(config);
|
|
64
|
+
return new import_client_ecs.ECSClient({
|
|
65
|
+
region,
|
|
66
|
+
...credentials && { credentials }
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
var extractTaskId = (taskArn) => {
|
|
70
|
+
const parts = taskArn.split("/");
|
|
71
|
+
return parts[parts.length - 1];
|
|
72
|
+
};
|
|
73
|
+
var fargate = (0, import_computesdk.createProvider)({
|
|
74
|
+
name: "fargate",
|
|
75
|
+
methods: {
|
|
76
|
+
sandbox: {
|
|
77
|
+
// Collection operations (compute.sandbox.*)
|
|
78
|
+
create: async (config, options) => {
|
|
79
|
+
const {
|
|
80
|
+
cluster,
|
|
81
|
+
taskDefinition,
|
|
82
|
+
subnets,
|
|
83
|
+
securityGroups,
|
|
84
|
+
assignPublicIp,
|
|
85
|
+
containerName
|
|
86
|
+
} = getAndValidateCredentials(config);
|
|
87
|
+
const client = createECSClient(config);
|
|
88
|
+
try {
|
|
89
|
+
const command = new import_client_ecs.RunTaskCommand({
|
|
90
|
+
cluster,
|
|
91
|
+
taskDefinition,
|
|
92
|
+
launchType: "FARGATE",
|
|
93
|
+
networkConfiguration: {
|
|
94
|
+
awsvpcConfiguration: {
|
|
95
|
+
subnets,
|
|
96
|
+
securityGroups,
|
|
97
|
+
assignPublicIp: assignPublicIp ? "ENABLED" : "DISABLED"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
// Container overrides for ECS are limited to environment variables,
|
|
101
|
+
// memory, CPU, and command - not the image itself
|
|
102
|
+
...containerName && {
|
|
103
|
+
overrides: {
|
|
104
|
+
containerOverrides: [
|
|
105
|
+
{
|
|
106
|
+
name: containerName
|
|
107
|
+
// Additional container overrides can be added here if needed
|
|
108
|
+
// such as environment variables, memory, CPU, etc.
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
const response = await client.send(command);
|
|
115
|
+
if (!response.tasks || response.tasks.length === 0) {
|
|
116
|
+
const failures = response.failures?.map((f) => `${f.reason}: ${f.detail}`).join(", ");
|
|
117
|
+
throw new Error(`No task created. Failures: ${failures || "unknown"}`);
|
|
118
|
+
}
|
|
119
|
+
const task = response.tasks[0];
|
|
120
|
+
if (!task.taskArn) {
|
|
121
|
+
throw new Error("Task ARN is undefined in response");
|
|
122
|
+
}
|
|
123
|
+
const fargateSandbox = {
|
|
124
|
+
taskArn: task.taskArn,
|
|
125
|
+
clusterArn: task.clusterArn || cluster,
|
|
126
|
+
taskId: extractTaskId(task.taskArn)
|
|
127
|
+
};
|
|
128
|
+
return {
|
|
129
|
+
sandbox: fargateSandbox,
|
|
130
|
+
sandboxId: task.taskArn
|
|
131
|
+
};
|
|
132
|
+
} catch (error) {
|
|
133
|
+
throw new Error(
|
|
134
|
+
`Failed to create Fargate sandbox: ${error instanceof Error ? error.message : String(error)}`
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
getById: async (config, sandboxId) => {
|
|
139
|
+
const { cluster } = getAndValidateCredentials(config);
|
|
140
|
+
const client = createECSClient(config);
|
|
141
|
+
try {
|
|
142
|
+
const command = new import_client_ecs.DescribeTasksCommand({
|
|
143
|
+
cluster,
|
|
144
|
+
tasks: [sandboxId]
|
|
145
|
+
});
|
|
146
|
+
const response = await client.send(command);
|
|
147
|
+
if (!response.tasks || response.tasks.length === 0) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
const task = response.tasks[0];
|
|
151
|
+
if (!task.taskArn) {
|
|
152
|
+
throw new Error("Task ARN is missing from response");
|
|
153
|
+
}
|
|
154
|
+
const fargateSandbox = {
|
|
155
|
+
taskArn: task.taskArn,
|
|
156
|
+
clusterArn: task.clusterArn || cluster,
|
|
157
|
+
taskId: extractTaskId(task.taskArn)
|
|
158
|
+
};
|
|
159
|
+
return {
|
|
160
|
+
sandbox: fargateSandbox,
|
|
161
|
+
sandboxId: task.taskArn
|
|
162
|
+
};
|
|
163
|
+
} catch (error) {
|
|
164
|
+
if (error instanceof Error && (error.message.includes("MISSING") || error.message.includes("not found"))) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
throw new Error(
|
|
168
|
+
`Failed to get Fargate sandbox: ${error instanceof Error ? error.message : String(error)}`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
list: async (config) => {
|
|
173
|
+
const { cluster } = getAndValidateCredentials(config);
|
|
174
|
+
const client = createECSClient(config);
|
|
175
|
+
try {
|
|
176
|
+
const listCommand = new import_client_ecs.ListTasksCommand({
|
|
177
|
+
cluster,
|
|
178
|
+
desiredStatus: "RUNNING"
|
|
179
|
+
});
|
|
180
|
+
const listResponse = await client.send(listCommand);
|
|
181
|
+
const taskArns = listResponse.taskArns || [];
|
|
182
|
+
if (taskArns.length === 0) {
|
|
183
|
+
return [];
|
|
184
|
+
}
|
|
185
|
+
const describeCommand = new import_client_ecs.DescribeTasksCommand({
|
|
186
|
+
cluster,
|
|
187
|
+
tasks: taskArns
|
|
188
|
+
});
|
|
189
|
+
const describeResponse = await client.send(describeCommand);
|
|
190
|
+
const tasks = describeResponse.tasks || [];
|
|
191
|
+
const sandboxes = tasks.filter((task) => task.taskArn).map((task) => {
|
|
192
|
+
const fargateSandbox = {
|
|
193
|
+
taskArn: task.taskArn,
|
|
194
|
+
clusterArn: task.clusterArn || cluster,
|
|
195
|
+
taskId: extractTaskId(task.taskArn)
|
|
196
|
+
};
|
|
197
|
+
return {
|
|
198
|
+
sandbox: fargateSandbox,
|
|
199
|
+
sandboxId: task.taskArn
|
|
200
|
+
};
|
|
201
|
+
});
|
|
202
|
+
return sandboxes;
|
|
203
|
+
} catch (error) {
|
|
204
|
+
throw new Error(
|
|
205
|
+
`Failed to list Fargate sandboxes: ${error instanceof Error ? error.message : String(error)}`
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
destroy: async (config, sandboxId) => {
|
|
210
|
+
const { cluster } = getAndValidateCredentials(config);
|
|
211
|
+
const client = createECSClient(config);
|
|
212
|
+
try {
|
|
213
|
+
const command = new import_client_ecs.StopTaskCommand({
|
|
214
|
+
cluster,
|
|
215
|
+
task: sandboxId,
|
|
216
|
+
reason: "User requested termination"
|
|
217
|
+
});
|
|
218
|
+
await client.send(command);
|
|
219
|
+
} catch (error) {
|
|
220
|
+
if (error instanceof Error && (error.message.includes("MISSING") || error.message.includes("not found") || error.message.includes("STOPPED"))) {
|
|
221
|
+
console.warn(`Fargate destroy warning: Task already stopped or not found`);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
console.warn(
|
|
225
|
+
`Fargate destroy warning: ${error instanceof Error ? error.message : String(error)}`
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
// Instance operations (minimal stubs - not implemented yet)
|
|
230
|
+
runCode: async (_sandbox, _code, _runtime) => {
|
|
231
|
+
throw new Error("Fargate runCode method not implemented yet");
|
|
232
|
+
},
|
|
233
|
+
runCommand: async (_sandbox, _command, _args, _options) => {
|
|
234
|
+
throw new Error("Fargate runCommand method not implemented yet");
|
|
235
|
+
},
|
|
236
|
+
getInfo: async (_sandbox) => {
|
|
237
|
+
throw new Error("Fargate getInfo method not implemented yet");
|
|
238
|
+
},
|
|
239
|
+
getUrl: async (_sandbox, _options) => {
|
|
240
|
+
throw new Error("Fargate getUrl method not implemented yet");
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
246
|
+
0 && (module.exports = {
|
|
247
|
+
fargate,
|
|
248
|
+
getAndValidateCredentials
|
|
249
|
+
});
|
|
250
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * AWS ECS Fargate Provider - Factory-based Implementation\n */\n\nimport { createProvider } from 'computesdk';\nimport type { Runtime, CreateSandboxOptions, RunCommandOptions } from 'computesdk';\nimport {\n ECSClient,\n RunTaskCommand,\n StopTaskCommand,\n DescribeTasksCommand,\n ListTasksCommand,\n} from '@aws-sdk/client-ecs';\n\n/**\n * Fargate sandbox interface\n */\ninterface FargateSandbox {\n taskArn: string;\n clusterArn: string;\n taskId: string;\n}\n\nexport interface FargateConfig {\n /** AWS Access Key ID - falls back to AWS_ACCESS_KEY_ID env var or default credential chain */\n accessKeyId?: string;\n /** AWS Secret Access Key - falls back to AWS_SECRET_ACCESS_KEY env var or default credential chain */\n secretAccessKey?: string;\n /** AWS Region - falls back to AWS_REGION env var */\n region?: string;\n /** ECS Cluster name or ARN */\n cluster: string;\n /** Task definition family name or ARN */\n taskDefinition: string;\n /** VPC Subnet IDs for task networking */\n subnets: string[];\n /** Security Group IDs for task networking */\n securityGroups: string[];\n /** Whether to assign a public IP (default: true) */\n assignPublicIp?: boolean;\n /** Container name in the task definition (default: 'sandbox') */\n containerName?: string;\n}\n\nexport const getAndValidateCredentials = (config: FargateConfig) => {\n const region = config.region || process.env?.AWS_REGION || 'us-east-1';\n const cluster = config.cluster;\n const taskDefinition = config.taskDefinition;\n const subnets = config.subnets;\n const securityGroups = config.securityGroups;\n\n if (!cluster) {\n throw new Error('Missing ECS cluster. Provide cluster in config.');\n }\n\n if (!taskDefinition) {\n throw new Error('Missing ECS task definition. Provide taskDefinition in config.');\n }\n\n if (!subnets || subnets.length === 0) {\n throw new Error('Missing subnets. Provide at least one subnet in config.');\n }\n\n if (!securityGroups || securityGroups.length === 0) {\n throw new Error('Missing security groups. Provide at least one security group in config.');\n }\n\n // Build credentials object only if explicitly provided\n // Otherwise, let the SDK use the default credential chain\n const credentials = config.accessKeyId && config.secretAccessKey\n ? {\n accessKeyId: config.accessKeyId,\n secretAccessKey: config.secretAccessKey,\n }\n : undefined;\n\n return {\n region,\n cluster,\n taskDefinition,\n subnets,\n securityGroups,\n credentials,\n assignPublicIp: config.assignPublicIp ?? true,\n containerName: config.containerName || 'sandbox',\n };\n};\n\n/**\n * Create an ECS client instance\n */\nconst createECSClient = (config: FargateConfig): ECSClient => {\n const { region, credentials } = getAndValidateCredentials(config);\n \n return new ECSClient({\n region,\n ...(credentials && { credentials }),\n });\n};\n\n/**\n * Extract task ID from task ARN\n * ARN format: arn:aws:ecs:region:account:task/cluster-name/task-id\n */\nconst extractTaskId = (taskArn: string): string => {\n const parts = taskArn.split('/');\n return parts[parts.length - 1];\n};\n\n/**\n * Normalize task identifier to full ARN if needed\n */\nconst normalizeTaskArn = (taskId: string, cluster: string, region: string, accountId?: string): string => {\n if (taskId.startsWith('arn:aws:ecs:')) {\n return taskId;\n }\n // If we don't have account ID, just return the task ID and let AWS resolve it\n return taskId;\n};\n\n/**\n * Create an AWS ECS Fargate provider instance using the factory pattern\n */\nexport const fargate = createProvider<FargateSandbox, FargateConfig>({\n name: 'fargate',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: FargateConfig, options?: CreateSandboxOptions) => {\n const {\n cluster,\n taskDefinition,\n subnets,\n securityGroups,\n assignPublicIp,\n containerName,\n } = getAndValidateCredentials(config);\n \n const client = createECSClient(config);\n\n try {\n // Note: For AWS ECS Fargate, the image is specified in the task definition,\n // not as a runtime override. The task definition should be pre-configured\n // with the appropriate image for the desired runtime.\n // \n // The options?.runtime parameter is acknowledged but the actual runtime\n // environment is determined by the pre-configured task definition.\n \n const command = new RunTaskCommand({\n cluster,\n taskDefinition,\n launchType: 'FARGATE',\n networkConfiguration: {\n awsvpcConfiguration: {\n subnets,\n securityGroups,\n assignPublicIp: assignPublicIp ? 'ENABLED' : 'DISABLED',\n },\n },\n // Container overrides for ECS are limited to environment variables, \n // memory, CPU, and command - not the image itself\n ...(containerName && {\n overrides: {\n containerOverrides: [\n {\n name: containerName,\n // Additional container overrides can be added here if needed\n // such as environment variables, memory, CPU, etc.\n },\n ],\n },\n }),\n });\n\n const response = await client.send(command);\n\n if (!response.tasks || response.tasks.length === 0) {\n const failures = response.failures?.map(f => `${f.reason}: ${f.detail}`).join(', ');\n throw new Error(`No task created. Failures: ${failures || 'unknown'}`);\n }\n\n const task = response.tasks[0];\n \n if (!task.taskArn) {\n throw new Error('Task ARN is undefined in response');\n }\n\n const fargateSandbox: FargateSandbox = {\n taskArn: task.taskArn,\n clusterArn: task.clusterArn || cluster,\n taskId: extractTaskId(task.taskArn),\n };\n\n return {\n sandbox: fargateSandbox,\n sandboxId: task.taskArn,\n };\n } catch (error) {\n throw new Error(\n `Failed to create Fargate sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: FargateConfig, sandboxId: string) => {\n const { cluster } = getAndValidateCredentials(config);\n const client = createECSClient(config);\n\n try {\n const command = new DescribeTasksCommand({\n cluster,\n tasks: [sandboxId],\n });\n\n const response = await client.send(command);\n\n if (!response.tasks || response.tasks.length === 0) {\n return null;\n }\n\n const task = response.tasks[0];\n \n if (!task.taskArn) {\n throw new Error('Task ARN is missing from response');\n }\n\n const fargateSandbox: FargateSandbox = {\n taskArn: task.taskArn,\n clusterArn: task.clusterArn || cluster,\n taskId: extractTaskId(task.taskArn),\n };\n\n return {\n sandbox: fargateSandbox,\n sandboxId: task.taskArn,\n };\n } catch (error) {\n // Handle task not found\n if (error instanceof Error && \n (error.message.includes('MISSING') || error.message.includes('not found'))) {\n return null;\n }\n throw new Error(\n `Failed to get Fargate sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n list: async (config: FargateConfig) => {\n const { cluster } = getAndValidateCredentials(config);\n const client = createECSClient(config);\n\n try {\n // Step 1: List task ARNs\n const listCommand = new ListTasksCommand({\n cluster,\n desiredStatus: 'RUNNING',\n });\n\n const listResponse = await client.send(listCommand);\n const taskArns = listResponse.taskArns || [];\n\n if (taskArns.length === 0) {\n return [];\n }\n\n // Step 2: Describe tasks to get full details\n const describeCommand = new DescribeTasksCommand({\n cluster,\n tasks: taskArns,\n });\n\n const describeResponse = await client.send(describeCommand);\n const tasks = describeResponse.tasks || [];\n\n // Transform each task into the expected format\n const sandboxes = tasks\n .filter(task => task.taskArn)\n .map(task => {\n const fargateSandbox: FargateSandbox = {\n taskArn: task.taskArn!,\n clusterArn: task.clusterArn || cluster,\n taskId: extractTaskId(task.taskArn!),\n };\n\n return {\n sandbox: fargateSandbox,\n sandboxId: task.taskArn!,\n };\n });\n\n return sandboxes;\n } catch (error) {\n throw new Error(\n `Failed to list Fargate sandboxes: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n destroy: async (config: FargateConfig, sandboxId: string) => {\n const { cluster } = getAndValidateCredentials(config);\n const client = createECSClient(config);\n\n try {\n const command = new StopTaskCommand({\n cluster,\n task: sandboxId,\n reason: 'User requested termination',\n });\n\n await client.send(command);\n } catch (error) {\n // For destroy operations, don't throw if task is already stopped/gone\n if (error instanceof Error && \n (error.message.includes('MISSING') || \n error.message.includes('not found') ||\n error.message.includes('STOPPED'))) {\n console.warn(`Fargate destroy warning: Task already stopped or not found`);\n return;\n }\n console.warn(\n `Fargate destroy warning: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Instance operations (minimal stubs - not implemented yet)\n runCode: async (_sandbox: FargateSandbox, _code: string, _runtime?: Runtime) => {\n throw new Error('Fargate runCode method not implemented yet');\n },\n\n runCommand: async (_sandbox: FargateSandbox, _command: string, _args?: string[], _options?: RunCommandOptions) => {\n throw new Error('Fargate runCommand method not implemented yet');\n },\n\n getInfo: async (_sandbox: FargateSandbox) => {\n throw new Error('Fargate getInfo method not implemented yet');\n },\n\n getUrl: async (_sandbox: FargateSandbox, _options: { port: number; protocol?: string }) => {\n throw new Error('Fargate getUrl method not implemented yet');\n },\n },\n },\n});"],"mappings":"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","names":[]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { createProvider } from "computesdk";
|
|
3
|
+
import {
|
|
4
|
+
ECSClient,
|
|
5
|
+
RunTaskCommand,
|
|
6
|
+
StopTaskCommand,
|
|
7
|
+
DescribeTasksCommand,
|
|
8
|
+
ListTasksCommand
|
|
9
|
+
} from "@aws-sdk/client-ecs";
|
|
10
|
+
var getAndValidateCredentials = (config) => {
|
|
11
|
+
const region = config.region || process.env?.AWS_REGION || "us-east-1";
|
|
12
|
+
const cluster = config.cluster;
|
|
13
|
+
const taskDefinition = config.taskDefinition;
|
|
14
|
+
const subnets = config.subnets;
|
|
15
|
+
const securityGroups = config.securityGroups;
|
|
16
|
+
if (!cluster) {
|
|
17
|
+
throw new Error("Missing ECS cluster. Provide cluster in config.");
|
|
18
|
+
}
|
|
19
|
+
if (!taskDefinition) {
|
|
20
|
+
throw new Error("Missing ECS task definition. Provide taskDefinition in config.");
|
|
21
|
+
}
|
|
22
|
+
if (!subnets || subnets.length === 0) {
|
|
23
|
+
throw new Error("Missing subnets. Provide at least one subnet in config.");
|
|
24
|
+
}
|
|
25
|
+
if (!securityGroups || securityGroups.length === 0) {
|
|
26
|
+
throw new Error("Missing security groups. Provide at least one security group in config.");
|
|
27
|
+
}
|
|
28
|
+
const credentials = config.accessKeyId && config.secretAccessKey ? {
|
|
29
|
+
accessKeyId: config.accessKeyId,
|
|
30
|
+
secretAccessKey: config.secretAccessKey
|
|
31
|
+
} : void 0;
|
|
32
|
+
return {
|
|
33
|
+
region,
|
|
34
|
+
cluster,
|
|
35
|
+
taskDefinition,
|
|
36
|
+
subnets,
|
|
37
|
+
securityGroups,
|
|
38
|
+
credentials,
|
|
39
|
+
assignPublicIp: config.assignPublicIp ?? true,
|
|
40
|
+
containerName: config.containerName || "sandbox"
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
var createECSClient = (config) => {
|
|
44
|
+
const { region, credentials } = getAndValidateCredentials(config);
|
|
45
|
+
return new ECSClient({
|
|
46
|
+
region,
|
|
47
|
+
...credentials && { credentials }
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
var extractTaskId = (taskArn) => {
|
|
51
|
+
const parts = taskArn.split("/");
|
|
52
|
+
return parts[parts.length - 1];
|
|
53
|
+
};
|
|
54
|
+
var fargate = createProvider({
|
|
55
|
+
name: "fargate",
|
|
56
|
+
methods: {
|
|
57
|
+
sandbox: {
|
|
58
|
+
// Collection operations (compute.sandbox.*)
|
|
59
|
+
create: async (config, options) => {
|
|
60
|
+
const {
|
|
61
|
+
cluster,
|
|
62
|
+
taskDefinition,
|
|
63
|
+
subnets,
|
|
64
|
+
securityGroups,
|
|
65
|
+
assignPublicIp,
|
|
66
|
+
containerName
|
|
67
|
+
} = getAndValidateCredentials(config);
|
|
68
|
+
const client = createECSClient(config);
|
|
69
|
+
try {
|
|
70
|
+
const command = new RunTaskCommand({
|
|
71
|
+
cluster,
|
|
72
|
+
taskDefinition,
|
|
73
|
+
launchType: "FARGATE",
|
|
74
|
+
networkConfiguration: {
|
|
75
|
+
awsvpcConfiguration: {
|
|
76
|
+
subnets,
|
|
77
|
+
securityGroups,
|
|
78
|
+
assignPublicIp: assignPublicIp ? "ENABLED" : "DISABLED"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
// Container overrides for ECS are limited to environment variables,
|
|
82
|
+
// memory, CPU, and command - not the image itself
|
|
83
|
+
...containerName && {
|
|
84
|
+
overrides: {
|
|
85
|
+
containerOverrides: [
|
|
86
|
+
{
|
|
87
|
+
name: containerName
|
|
88
|
+
// Additional container overrides can be added here if needed
|
|
89
|
+
// such as environment variables, memory, CPU, etc.
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
const response = await client.send(command);
|
|
96
|
+
if (!response.tasks || response.tasks.length === 0) {
|
|
97
|
+
const failures = response.failures?.map((f) => `${f.reason}: ${f.detail}`).join(", ");
|
|
98
|
+
throw new Error(`No task created. Failures: ${failures || "unknown"}`);
|
|
99
|
+
}
|
|
100
|
+
const task = response.tasks[0];
|
|
101
|
+
if (!task.taskArn) {
|
|
102
|
+
throw new Error("Task ARN is undefined in response");
|
|
103
|
+
}
|
|
104
|
+
const fargateSandbox = {
|
|
105
|
+
taskArn: task.taskArn,
|
|
106
|
+
clusterArn: task.clusterArn || cluster,
|
|
107
|
+
taskId: extractTaskId(task.taskArn)
|
|
108
|
+
};
|
|
109
|
+
return {
|
|
110
|
+
sandbox: fargateSandbox,
|
|
111
|
+
sandboxId: task.taskArn
|
|
112
|
+
};
|
|
113
|
+
} catch (error) {
|
|
114
|
+
throw new Error(
|
|
115
|
+
`Failed to create Fargate sandbox: ${error instanceof Error ? error.message : String(error)}`
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
getById: async (config, sandboxId) => {
|
|
120
|
+
const { cluster } = getAndValidateCredentials(config);
|
|
121
|
+
const client = createECSClient(config);
|
|
122
|
+
try {
|
|
123
|
+
const command = new DescribeTasksCommand({
|
|
124
|
+
cluster,
|
|
125
|
+
tasks: [sandboxId]
|
|
126
|
+
});
|
|
127
|
+
const response = await client.send(command);
|
|
128
|
+
if (!response.tasks || response.tasks.length === 0) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
const task = response.tasks[0];
|
|
132
|
+
if (!task.taskArn) {
|
|
133
|
+
throw new Error("Task ARN is missing from response");
|
|
134
|
+
}
|
|
135
|
+
const fargateSandbox = {
|
|
136
|
+
taskArn: task.taskArn,
|
|
137
|
+
clusterArn: task.clusterArn || cluster,
|
|
138
|
+
taskId: extractTaskId(task.taskArn)
|
|
139
|
+
};
|
|
140
|
+
return {
|
|
141
|
+
sandbox: fargateSandbox,
|
|
142
|
+
sandboxId: task.taskArn
|
|
143
|
+
};
|
|
144
|
+
} catch (error) {
|
|
145
|
+
if (error instanceof Error && (error.message.includes("MISSING") || error.message.includes("not found"))) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
throw new Error(
|
|
149
|
+
`Failed to get Fargate sandbox: ${error instanceof Error ? error.message : String(error)}`
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
list: async (config) => {
|
|
154
|
+
const { cluster } = getAndValidateCredentials(config);
|
|
155
|
+
const client = createECSClient(config);
|
|
156
|
+
try {
|
|
157
|
+
const listCommand = new ListTasksCommand({
|
|
158
|
+
cluster,
|
|
159
|
+
desiredStatus: "RUNNING"
|
|
160
|
+
});
|
|
161
|
+
const listResponse = await client.send(listCommand);
|
|
162
|
+
const taskArns = listResponse.taskArns || [];
|
|
163
|
+
if (taskArns.length === 0) {
|
|
164
|
+
return [];
|
|
165
|
+
}
|
|
166
|
+
const describeCommand = new DescribeTasksCommand({
|
|
167
|
+
cluster,
|
|
168
|
+
tasks: taskArns
|
|
169
|
+
});
|
|
170
|
+
const describeResponse = await client.send(describeCommand);
|
|
171
|
+
const tasks = describeResponse.tasks || [];
|
|
172
|
+
const sandboxes = tasks.filter((task) => task.taskArn).map((task) => {
|
|
173
|
+
const fargateSandbox = {
|
|
174
|
+
taskArn: task.taskArn,
|
|
175
|
+
clusterArn: task.clusterArn || cluster,
|
|
176
|
+
taskId: extractTaskId(task.taskArn)
|
|
177
|
+
};
|
|
178
|
+
return {
|
|
179
|
+
sandbox: fargateSandbox,
|
|
180
|
+
sandboxId: task.taskArn
|
|
181
|
+
};
|
|
182
|
+
});
|
|
183
|
+
return sandboxes;
|
|
184
|
+
} catch (error) {
|
|
185
|
+
throw new Error(
|
|
186
|
+
`Failed to list Fargate sandboxes: ${error instanceof Error ? error.message : String(error)}`
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
destroy: async (config, sandboxId) => {
|
|
191
|
+
const { cluster } = getAndValidateCredentials(config);
|
|
192
|
+
const client = createECSClient(config);
|
|
193
|
+
try {
|
|
194
|
+
const command = new StopTaskCommand({
|
|
195
|
+
cluster,
|
|
196
|
+
task: sandboxId,
|
|
197
|
+
reason: "User requested termination"
|
|
198
|
+
});
|
|
199
|
+
await client.send(command);
|
|
200
|
+
} catch (error) {
|
|
201
|
+
if (error instanceof Error && (error.message.includes("MISSING") || error.message.includes("not found") || error.message.includes("STOPPED"))) {
|
|
202
|
+
console.warn(`Fargate destroy warning: Task already stopped or not found`);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
console.warn(
|
|
206
|
+
`Fargate destroy warning: ${error instanceof Error ? error.message : String(error)}`
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
// Instance operations (minimal stubs - not implemented yet)
|
|
211
|
+
runCode: async (_sandbox, _code, _runtime) => {
|
|
212
|
+
throw new Error("Fargate runCode method not implemented yet");
|
|
213
|
+
},
|
|
214
|
+
runCommand: async (_sandbox, _command, _args, _options) => {
|
|
215
|
+
throw new Error("Fargate runCommand method not implemented yet");
|
|
216
|
+
},
|
|
217
|
+
getInfo: async (_sandbox) => {
|
|
218
|
+
throw new Error("Fargate getInfo method not implemented yet");
|
|
219
|
+
},
|
|
220
|
+
getUrl: async (_sandbox, _options) => {
|
|
221
|
+
throw new Error("Fargate getUrl method not implemented yet");
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
export {
|
|
227
|
+
fargate,
|
|
228
|
+
getAndValidateCredentials
|
|
229
|
+
};
|
|
230
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * AWS ECS Fargate Provider - Factory-based Implementation\n */\n\nimport { createProvider } from 'computesdk';\nimport type { Runtime, CreateSandboxOptions, RunCommandOptions } from 'computesdk';\nimport {\n ECSClient,\n RunTaskCommand,\n StopTaskCommand,\n DescribeTasksCommand,\n ListTasksCommand,\n} from '@aws-sdk/client-ecs';\n\n/**\n * Fargate sandbox interface\n */\ninterface FargateSandbox {\n taskArn: string;\n clusterArn: string;\n taskId: string;\n}\n\nexport interface FargateConfig {\n /** AWS Access Key ID - falls back to AWS_ACCESS_KEY_ID env var or default credential chain */\n accessKeyId?: string;\n /** AWS Secret Access Key - falls back to AWS_SECRET_ACCESS_KEY env var or default credential chain */\n secretAccessKey?: string;\n /** AWS Region - falls back to AWS_REGION env var */\n region?: string;\n /** ECS Cluster name or ARN */\n cluster: string;\n /** Task definition family name or ARN */\n taskDefinition: string;\n /** VPC Subnet IDs for task networking */\n subnets: string[];\n /** Security Group IDs for task networking */\n securityGroups: string[];\n /** Whether to assign a public IP (default: true) */\n assignPublicIp?: boolean;\n /** Container name in the task definition (default: 'sandbox') */\n containerName?: string;\n}\n\nexport const getAndValidateCredentials = (config: FargateConfig) => {\n const region = config.region || process.env?.AWS_REGION || 'us-east-1';\n const cluster = config.cluster;\n const taskDefinition = config.taskDefinition;\n const subnets = config.subnets;\n const securityGroups = config.securityGroups;\n\n if (!cluster) {\n throw new Error('Missing ECS cluster. Provide cluster in config.');\n }\n\n if (!taskDefinition) {\n throw new Error('Missing ECS task definition. Provide taskDefinition in config.');\n }\n\n if (!subnets || subnets.length === 0) {\n throw new Error('Missing subnets. Provide at least one subnet in config.');\n }\n\n if (!securityGroups || securityGroups.length === 0) {\n throw new Error('Missing security groups. Provide at least one security group in config.');\n }\n\n // Build credentials object only if explicitly provided\n // Otherwise, let the SDK use the default credential chain\n const credentials = config.accessKeyId && config.secretAccessKey\n ? {\n accessKeyId: config.accessKeyId,\n secretAccessKey: config.secretAccessKey,\n }\n : undefined;\n\n return {\n region,\n cluster,\n taskDefinition,\n subnets,\n securityGroups,\n credentials,\n assignPublicIp: config.assignPublicIp ?? true,\n containerName: config.containerName || 'sandbox',\n };\n};\n\n/**\n * Create an ECS client instance\n */\nconst createECSClient = (config: FargateConfig): ECSClient => {\n const { region, credentials } = getAndValidateCredentials(config);\n \n return new ECSClient({\n region,\n ...(credentials && { credentials }),\n });\n};\n\n/**\n * Extract task ID from task ARN\n * ARN format: arn:aws:ecs:region:account:task/cluster-name/task-id\n */\nconst extractTaskId = (taskArn: string): string => {\n const parts = taskArn.split('/');\n return parts[parts.length - 1];\n};\n\n/**\n * Normalize task identifier to full ARN if needed\n */\nconst normalizeTaskArn = (taskId: string, cluster: string, region: string, accountId?: string): string => {\n if (taskId.startsWith('arn:aws:ecs:')) {\n return taskId;\n }\n // If we don't have account ID, just return the task ID and let AWS resolve it\n return taskId;\n};\n\n/**\n * Create an AWS ECS Fargate provider instance using the factory pattern\n */\nexport const fargate = createProvider<FargateSandbox, FargateConfig>({\n name: 'fargate',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: FargateConfig, options?: CreateSandboxOptions) => {\n const {\n cluster,\n taskDefinition,\n subnets,\n securityGroups,\n assignPublicIp,\n containerName,\n } = getAndValidateCredentials(config);\n \n const client = createECSClient(config);\n\n try {\n // Note: For AWS ECS Fargate, the image is specified in the task definition,\n // not as a runtime override. The task definition should be pre-configured\n // with the appropriate image for the desired runtime.\n // \n // The options?.runtime parameter is acknowledged but the actual runtime\n // environment is determined by the pre-configured task definition.\n \n const command = new RunTaskCommand({\n cluster,\n taskDefinition,\n launchType: 'FARGATE',\n networkConfiguration: {\n awsvpcConfiguration: {\n subnets,\n securityGroups,\n assignPublicIp: assignPublicIp ? 'ENABLED' : 'DISABLED',\n },\n },\n // Container overrides for ECS are limited to environment variables, \n // memory, CPU, and command - not the image itself\n ...(containerName && {\n overrides: {\n containerOverrides: [\n {\n name: containerName,\n // Additional container overrides can be added here if needed\n // such as environment variables, memory, CPU, etc.\n },\n ],\n },\n }),\n });\n\n const response = await client.send(command);\n\n if (!response.tasks || response.tasks.length === 0) {\n const failures = response.failures?.map(f => `${f.reason}: ${f.detail}`).join(', ');\n throw new Error(`No task created. Failures: ${failures || 'unknown'}`);\n }\n\n const task = response.tasks[0];\n \n if (!task.taskArn) {\n throw new Error('Task ARN is undefined in response');\n }\n\n const fargateSandbox: FargateSandbox = {\n taskArn: task.taskArn,\n clusterArn: task.clusterArn || cluster,\n taskId: extractTaskId(task.taskArn),\n };\n\n return {\n sandbox: fargateSandbox,\n sandboxId: task.taskArn,\n };\n } catch (error) {\n throw new Error(\n `Failed to create Fargate sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: FargateConfig, sandboxId: string) => {\n const { cluster } = getAndValidateCredentials(config);\n const client = createECSClient(config);\n\n try {\n const command = new DescribeTasksCommand({\n cluster,\n tasks: [sandboxId],\n });\n\n const response = await client.send(command);\n\n if (!response.tasks || response.tasks.length === 0) {\n return null;\n }\n\n const task = response.tasks[0];\n \n if (!task.taskArn) {\n throw new Error('Task ARN is missing from response');\n }\n\n const fargateSandbox: FargateSandbox = {\n taskArn: task.taskArn,\n clusterArn: task.clusterArn || cluster,\n taskId: extractTaskId(task.taskArn),\n };\n\n return {\n sandbox: fargateSandbox,\n sandboxId: task.taskArn,\n };\n } catch (error) {\n // Handle task not found\n if (error instanceof Error && \n (error.message.includes('MISSING') || error.message.includes('not found'))) {\n return null;\n }\n throw new Error(\n `Failed to get Fargate sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n list: async (config: FargateConfig) => {\n const { cluster } = getAndValidateCredentials(config);\n const client = createECSClient(config);\n\n try {\n // Step 1: List task ARNs\n const listCommand = new ListTasksCommand({\n cluster,\n desiredStatus: 'RUNNING',\n });\n\n const listResponse = await client.send(listCommand);\n const taskArns = listResponse.taskArns || [];\n\n if (taskArns.length === 0) {\n return [];\n }\n\n // Step 2: Describe tasks to get full details\n const describeCommand = new DescribeTasksCommand({\n cluster,\n tasks: taskArns,\n });\n\n const describeResponse = await client.send(describeCommand);\n const tasks = describeResponse.tasks || [];\n\n // Transform each task into the expected format\n const sandboxes = tasks\n .filter(task => task.taskArn)\n .map(task => {\n const fargateSandbox: FargateSandbox = {\n taskArn: task.taskArn!,\n clusterArn: task.clusterArn || cluster,\n taskId: extractTaskId(task.taskArn!),\n };\n\n return {\n sandbox: fargateSandbox,\n sandboxId: task.taskArn!,\n };\n });\n\n return sandboxes;\n } catch (error) {\n throw new Error(\n `Failed to list Fargate sandboxes: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n destroy: async (config: FargateConfig, sandboxId: string) => {\n const { cluster } = getAndValidateCredentials(config);\n const client = createECSClient(config);\n\n try {\n const command = new StopTaskCommand({\n cluster,\n task: sandboxId,\n reason: 'User requested termination',\n });\n\n await client.send(command);\n } catch (error) {\n // For destroy operations, don't throw if task is already stopped/gone\n if (error instanceof Error && \n (error.message.includes('MISSING') || \n error.message.includes('not found') ||\n error.message.includes('STOPPED'))) {\n console.warn(`Fargate destroy warning: Task already stopped or not found`);\n return;\n }\n console.warn(\n `Fargate destroy warning: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Instance operations (minimal stubs - not implemented yet)\n runCode: async (_sandbox: FargateSandbox, _code: string, _runtime?: Runtime) => {\n throw new Error('Fargate runCode method not implemented yet');\n },\n\n runCommand: async (_sandbox: FargateSandbox, _command: string, _args?: string[], _options?: RunCommandOptions) => {\n throw new Error('Fargate runCommand method not implemented yet');\n },\n\n getInfo: async (_sandbox: FargateSandbox) => {\n throw new Error('Fargate getInfo method not implemented yet');\n },\n\n getUrl: async (_sandbox: FargateSandbox, _options: { port: number; protocol?: string }) => {\n throw new Error('Fargate getUrl method not implemented yet');\n },\n },\n },\n});"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@computesdk/aws-ecs",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "AWS ECS provider for ComputeSDK",
|
|
5
|
+
"author": "ComputeSDK Team",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"module": "./dist/index.mjs",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.mjs",
|
|
14
|
+
"require": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@aws-sdk/client-ecs": "^3.943.0",
|
|
22
|
+
"computesdk": "1.8.8"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"aws",
|
|
26
|
+
"sandbox",
|
|
27
|
+
"code-execution",
|
|
28
|
+
"cloud",
|
|
29
|
+
"compute",
|
|
30
|
+
"containers",
|
|
31
|
+
"ecs"
|
|
32
|
+
],
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/computesdk/computesdk.git",
|
|
36
|
+
"directory": "packages/aws-ecs"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://github.com/computesdk/computesdk/tree/main/packages/aws-ecs",
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/computesdk/computesdk/issues"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/node": "^20.0.0",
|
|
44
|
+
"@vitest/coverage-v8": "^1.0.0",
|
|
45
|
+
"eslint": "^8.37.0",
|
|
46
|
+
"rimraf": "^5.0.0",
|
|
47
|
+
"tsup": "^8.0.0",
|
|
48
|
+
"typescript": "^5.0.0",
|
|
49
|
+
"vitest": "^1.0.0",
|
|
50
|
+
"@computesdk/test-utils": "1.4.1"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "tsup",
|
|
54
|
+
"clean": "rimraf dist",
|
|
55
|
+
"dev": "tsup --watch",
|
|
56
|
+
"test": "vitest run",
|
|
57
|
+
"test:watch": "vitest watch",
|
|
58
|
+
"test:coverage": "vitest run --coverage",
|
|
59
|
+
"typecheck": "tsc --noEmit",
|
|
60
|
+
"lint": "eslint"
|
|
61
|
+
}
|
|
62
|
+
}
|