UNPKG

ecs-pf

Version:

CLI for port-forwarding to RDS via AWS ECS

325 lines (324 loc) 11.1 kB
import { array, boolean, custom, literal, minLength, number, object, optional, pipe, string, transform, union, } from "valibot"; import { ClusterArnSchema, ClusterNameSchema, CommandSchema, ContainerNameSchema, DatabaseEngineSchema, DBEndpointSchema, DBInstanceIdentifierSchema, DBInstanceStatusSchema, ECSClientSchema, NonEmptyStringSchema, PortSchema, RegionNameSchema, RuntimeIdSchema, ServiceNameSchema, TaskArnSchema, TaskIdSchema, TaskStatusSchema, VpcSecurityGroupsSchema, } from "./branded.js"; export const RDSInstanceSchema = object({ dbInstanceIdentifier: DBInstanceIdentifierSchema, endpoint: DBEndpointSchema, port: PortSchema, engine: DatabaseEngineSchema, dbInstanceClass: string(), dbInstanceStatus: DBInstanceStatusSchema, allocatedStorage: number(), availabilityZone: string(), vpcSecurityGroups: VpcSecurityGroupsSchema, dbSubnetGroup: optional(string()), createdTime: optional(pipe(union([string(), custom((input) => input instanceof Date)]), transform((input) => { if (input instanceof Date) return input; return new Date(input); }))), }); export const ConnectDryRunParamsSchema = object({ region: RegionNameSchema, cluster: ClusterNameSchema, task: TaskIdSchema, rdsInstance: RDSInstanceSchema, rdsPort: PortSchema, localPort: PortSchema, }); export const ExecDryRunParamsSchema = object({ region: RegionNameSchema, cluster: ClusterNameSchema, task: TaskIdSchema, container: ContainerNameSchema, command: CommandSchema, }); export const ReproducibleCommandParamsSchema = object({ region: RegionNameSchema, cluster: ClusterNameSchema, task: TaskArnSchema, rds: DBInstanceIdentifierSchema, rdsPort: PortSchema, localPort: PortSchema, }); export const SSMSessionParamsSchema = object({ taskArn: TaskArnSchema, rdsInstance: RDSInstanceSchema, rdsPort: PortSchema, localPort: PortSchema, reproducibleCommand: optional(NonEmptyStringSchema), }); export const ECSExecParamsSchema = object({ region: RegionNameSchema, clusterName: ClusterNameSchema, taskArn: union([TaskArnSchema, TaskIdSchema]), containerName: ContainerNameSchema, command: CommandSchema, }); export const TaskScoringParamsSchema = object({ ecsClient: ECSClientSchema, tasks: array(object({ taskArn: TaskArnSchema, displayName: string(), runtimeId: RuntimeIdSchema, taskId: TaskIdSchema, clusterName: ClusterNameSchema, serviceName: ServiceNameSchema, taskStatus: TaskStatusSchema, })), cluster: object({ clusterName: ClusterNameSchema, clusterArn: ClusterArnSchema, }), rdsInstance: RDSInstanceSchema, analysisResults: object({ environment: array(object({ rds_identifier: string(), task_family: optional(string()), confidence: union([literal("high"), literal("medium"), literal("low")]), key: string(), value: string(), score: number(), })), naming: array(object({ pattern: string(), score: number(), reason: string(), })), network: array(object({ subnet: string(), score: number(), accessible: boolean(), })), }), }); export const ECSTargetSelectionOptionsSchema = object({ cluster: optional(ClusterNameSchema), task: optional(TaskIdSchema), }); export const ECSTargetSelectionParamsSchema = object({ ecsClient: ECSClientSchema, selectedRDS: RDSInstanceSchema, options: ECSTargetSelectionOptionsSchema, selections: object({ region: string(), ecsCluster: optional(string()), localPort: optional(string()), }), }); export const TaskEnvironmentCheckParamsSchema = object({ ecsClient: ECSClientSchema, task: object({ taskArn: TaskArnSchema, displayName: string(), runtimeId: RuntimeIdSchema, taskId: TaskIdSchema, clusterName: ClusterNameSchema, serviceName: ServiceNameSchema, taskStatus: TaskStatusSchema, }), rdsInstance: RDSInstanceSchema, }); export const TaskNamingScoringParamsSchema = object({ tasks: array(object({ taskArn: TaskArnSchema, displayName: string(), runtimeId: RuntimeIdSchema, taskId: TaskIdSchema, clusterName: ClusterNameSchema, serviceName: ServiceNameSchema, taskStatus: TaskStatusSchema, })), cluster: object({ clusterName: ClusterNameSchema, clusterArn: ClusterArnSchema, }), rdsInstance: RDSInstanceSchema, }); export const ECSTaskContainersParamsSchema = object({ ecsClient: ECSClientSchema, clusterName: ClusterNameSchema, taskArn: TaskArnSchema, }); export const SearchParamsSchema = object({ items: array(union([ object({ clusterName: ClusterNameSchema }), object({ dbInstanceIdentifier: DBInstanceIdentifierSchema }), object({ taskArn: TaskArnSchema }), object({ regionName: RegionNameSchema }), ])), input: pipe(string(), minLength(0)), defaultValue: optional(union([string(), object({})])), }); export const ClusterInferenceParamsSchema = object({ rdsName: DBInstanceIdentifierSchema, allClusters: array(object({ clusterName: ClusterNameSchema, clusterArn: ClusterArnSchema, })), }); export const UniversalSearchConfigSchema = object({ items: array(union([ object({ clusterName: ClusterNameSchema }), object({ dbInstanceIdentifier: DBInstanceIdentifierSchema }), object({ taskArn: TaskArnSchema }), object({ regionName: RegionNameSchema }), ])), searchKeys: array(string()), displayFormatter: custom((input) => { return typeof input === "function"; }, "Invalid display formatter function"), emptyInputFormatter: optional(custom((input) => { return typeof input === "function"; }, "Invalid empty input formatter function")), threshold: optional(number()), distance: optional(number()), pageSize: optional(number()), }); export const UniversalSearchParamsSchema = object({ config: UniversalSearchConfigSchema, input: string(), defaultValue: optional(union([string(), object({})])), }); export const KeywordSearchParamsSchema = object({ items: array(union([ object({ clusterName: ClusterNameSchema }), object({ dbInstanceIdentifier: DBInstanceIdentifierSchema }), object({ taskArn: TaskArnSchema }), ])), input: string(), searchFields: custom((input) => { return typeof input === "function"; }, "Invalid search fields function"), }); export const SearchRegionsParamsSchema = object({ regions: array(object({ regionName: RegionNameSchema, optInStatus: string(), })), input: string(), defaultRegion: optional(string()), }); export const SearchClustersParamsSchema = object({ clusters: array(object({ clusterName: ClusterNameSchema, clusterArn: ClusterArnSchema, })), input: string(), }); export const SearchTasksParamsSchema = object({ tasks: array(object({ taskArn: TaskArnSchema, displayName: string(), runtimeId: RuntimeIdSchema, taskId: TaskIdSchema, clusterName: ClusterNameSchema, serviceName: ServiceNameSchema, taskStatus: TaskStatusSchema, })), input: string(), }); export const SearchRDSParamsSchema = object({ rdsInstances: array(RDSInstanceSchema), input: string(), }); export const SearchContainersParamsSchema = object({ containers: array(string()), input: string(), }); export const SearchInferenceResultsParamsSchema = object({ results: array(object({ cluster: object({ clusterName: ClusterNameSchema, clusterArn: ClusterArnSchema, }), score: number(), reasons: array(string()), })), input: string(), }); export const ConnectOptionsSchema = object({ region: optional(RegionNameSchema), cluster: optional(ClusterNameSchema), task: optional(pipe(string(), minLength(1, "Task ID cannot be empty"), transform((task) => task))), rds: optional(pipe(string(), minLength(1, "RDS instance identifier cannot be empty"), transform((rds) => rds))), rdsPort: optional(PortSchema), localPort: optional(PortSchema), dryRun: optional(boolean(), false), }); export const ExecOptionsSchema = object({ region: optional(RegionNameSchema), cluster: optional(ClusterNameSchema), task: optional(TaskIdSchema), container: optional(ContainerNameSchema), command: optional(CommandSchema), dryRun: optional(boolean()), }); export const EnableExecOptionsSchema = object({ region: optional(RegionNameSchema), cluster: optional(ClusterNameSchema), service: optional(ServiceNameSchema), dryRun: optional(boolean()), }); export const ECSServiceSchema = object({ serviceName: ServiceNameSchema, serviceArn: string(), clusterName: ClusterNameSchema, status: string(), taskDefinition: string(), enableExecuteCommand: boolean(), desiredCount: number(), runningCount: number(), pendingCount: number(), }); export const EnableExecResultSchema = object({ serviceName: ServiceNameSchema, clusterName: ClusterNameSchema, previousState: boolean(), newState: boolean(), success: boolean(), error: optional(string()), }); export const SelectionStateSchema = object({ region: optional(RegionNameSchema), rds: optional(DBInstanceIdentifierSchema), rdsPort: optional(PortSchema), ecsTarget: optional(string()), ecsCluster: optional(string()), localPort: optional(PortSchema), }); export const ECSClusterSchema = object({ clusterName: ClusterNameSchema, clusterArn: ClusterArnSchema, }); export const ProcessClusterServicesParamsSchema = object({ ecsClient: ECSClientSchema, cluster: ECSClusterSchema, options: EnableExecOptionsSchema, }); export const InferenceResultSchema = object({ cluster: ECSClusterSchema, score: number(), reasons: array(string()), task: object({ taskArn: TaskArnSchema, displayName: string(), runtimeId: RuntimeIdSchema, taskId: TaskIdSchema, clusterName: ClusterNameSchema, serviceName: ServiceNameSchema, taskStatus: TaskStatusSchema, createdAt: optional(pipe(union([string(), custom((input) => input instanceof Date)]), transform((input) => { if (input instanceof Date) return input; return new Date(input); }))), }), }); export const HandleConnectionParamsSchema = object({ selections: SelectionStateSchema, selectedRDS: RDSInstanceSchema, selectedTask: TaskArnSchema, selectedInference: InferenceResultSchema, rdsPort: PortSchema, options: object({ dryRun: optional(boolean()) }), });