// Copyright Abridged, Inc. 2023,2024. All Rights Reserved. // Node module: @collabland/aws // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT import { Container, DescribeTasksCommand, ECSClient, ECSClientConfig, ExecuteCommandCommand, ListClustersCommand, ListServicesCommand, ListTasksCommand, } from '@aws-sdk/client-ecs'; import {loggers} from '@collabland/common'; import {getAWSECSRegion, getDefaultConfig} from '../common/types.js'; const {trace} = loggers('collabland:aws:ecs'); export class ECSServiceClient { readonly client: ECSClient; constructor(options?: ECSClientConfig) { options = { ...getDefaultConfig(), region: getAWSECSRegion(), ...options, }; trace('ECS client config: %O', options); this.client = new ECSClient(options); } async listClusters() { const request = new ListClustersCommand({maxResults: 100}); const response = await this.client.send(request); return response.clusterArns ?? []; } async listServices(cluster?: string) { const request = new ListServicesCommand({cluster, maxResults: 100}); const response = await this.client.send(request); return response.serviceArns ?? []; } async listTasks(cluster?: string, serviceName?: string) { const request = new ListTasksCommand({ cluster, serviceName, maxResults: 100, }); const response = await this.client.send(request); return response.taskArns ?? []; } async describeTasks(cluster: string, tasks: string[]) { const request = new DescribeTasksCommand({ cluster, tasks, }); const response = await this.client.send(request); return response.tasks ?? []; } async listContainers( cluster: string, tasksArns: string[], containerFilter?: (container: Container) => boolean | undefined, ) { const tasks = await this.describeTasks(cluster, tasksArns); const list = tasks.map(t => { const containers = t.containers?.filter(c => containerFilter?.(c) ?? true) ?? []; return ( containers.map(c => ({ cluster: t.clusterArn, task: t.taskArn, container: c.name, })) ?? [] ); }); return list.flat(); } async executeCommand( cluster: string, task: string, container: string, command = '/bin/bash', interactive = true, ) { const request = new ExecuteCommandCommand({ cluster, task, container, command, interactive, }); const response = await this.client.send(request); return response.session; } }