import type {CloudProvider, FieldSchema, ServiceSchema, TableColumnSchema} from './types' /** CreatePipe's name rule. */ export const PIPE_NAME_PATTERN = '^[\\.\\-_A-Za-z0-9]{1,64}$' export const PIPE_STARTING_POSITIONS = ['TRIM_HORIZON', 'LATEST'] as const /** * The sources and targets the runtime's pipe poller actually moves events * between, keyed by the ARN's service field. Anything else is refused on create * rather than accepted into a pipe that would never deliver. */ export const PIPE_SOURCE_SERVICES = {sqs: 'SQS queue', kinesis: 'Kinesis stream', dynamodb: 'DynamoDB stream', kafka: 'MSK topic'} as const export const PIPE_TARGET_SERVICES = {lambda: 'Lambda function', sqs: 'SQS queue', sns: 'SNS topic', events: 'EventBridge event bus', states: 'Step Functions state machine'} as const export const PIPE_ENRICHMENT_SERVICES = {lambda: 'Lambda function', states: 'Step Functions state machine'} as const const ARN = '^arn:aws[a-z-]*:[a-z0-9-]+:[a-z0-9-]*:\\d{12}:.+$' const pipeColumns: TableColumnSchema[] = [ {name: 'name', label: 'Name'}, {name: 'status', label: 'State', format: 'badge'}, {name: 'source', label: 'Source', path: 'metadata.sourceName'}, {name: 'target', label: 'Target', path: 'metadata.targetName'}, {name: 'createdAt', label: 'Created', format: 'datetime'}, ] const pipeFilters: FieldSchema[] = [{name: 'search', label: 'Search', type: 'text', required: false}] export function awsPipesSchema(): ServiceSchema { return { cloud: 'aws', service: 'pipes', displayName: 'EventBridge Pipes', fields: [ { name: 'name', label: 'Name', type: 'text', required: true, validation: {pattern: PIPE_NAME_PATTERN, message: 'Use up to 64 letters, numbers, dots, dashes and underscores'}, }, {name: 'description', label: 'Description', type: 'text', required: false, validation: {maxLength: 512}}, { name: 'source', label: 'Source ARN', type: 'text', required: true, span: true, description: 'Where events come from: an SQS queue, a Kinesis stream, a DynamoDB stream or an MSK cluster.', validation: {pattern: ARN, message: 'Use the ARN of a queue or stream'}, }, { name: 'startingPosition', label: 'Starting position', type: 'select', required: false, defaultValue: 'LATEST', description: 'For streams and MSK: read new records only, or everything still in the stream.', options: [ {label: 'New records only (LATEST)', value: 'LATEST'}, {label: 'Oldest record (TRIM_HORIZON)', value: 'TRIM_HORIZON'}, ], }, { name: 'topicName', label: 'MSK topic', type: 'text', required: false, description: 'Required when the source is an MSK cluster.', }, { name: 'batchSize', label: 'Batch size', type: 'text', required: false, description: 'Records sent to the target at once. 1 to 10,000; leave empty for the default of 10.', validation: {pattern: '^[1-9][0-9]{0,4}$', message: 'Use a whole number from 1 to 10000'}, }, { name: 'filterPattern', label: 'Filter pattern', type: 'textarea', required: false, span: true, description: 'Optional EventBridge event pattern; only matching records go on. For SQS, match the parsed message under body, for example {"body": {"kind": ["order"]}}.', }, { name: 'enrichment', label: 'Enrichment ARN', type: 'text', required: false, span: true, description: 'Optional Lambda function or Step Functions state machine that transforms each batch before the target gets it.', validation: {pattern: ARN, message: 'Use the ARN of a Lambda function or state machine'}, }, { name: 'target', label: 'Target ARN', type: 'text', required: true, span: true, description: 'Where events go: a Lambda function, SQS queue, SNS topic, EventBridge event bus or Step Functions state machine.', validation: {pattern: ARN, message: 'Use the ARN of the target'}, }, { name: 'inputTemplate', label: 'Target input template', type: 'textarea', required: false, span: true, description: 'Optional. Reshape what the target receives, with <$.path> placeholders, for example {"id": <$.messageId>}.', }, { name: 'roleArn', label: 'Execution role ARN', type: 'text', required: true, span: true, description: 'The IAM role the pipe uses to read the source and call the target, as AWS requires. Create one in IAM first.', validation: {pattern: '^arn:aws[a-z-]*:iam::\\d{12}:role/.+$', message: 'Use an IAM role ARN such as arn:aws:iam::000000000000:role/pipe-role'}, }, { name: 'desiredState', label: 'State after creating', type: 'select', required: false, defaultValue: 'RUNNING', options: [ {label: 'Running', value: 'RUNNING'}, {label: 'Stopped', value: 'STOPPED'}, ], }, ], actions: ['list', 'create', 'delete', 'inspect'], capabilities: { resourceActions: [ {name: 'list', label: 'List pipes', enabled: true, status: 'available', runtimeRequired: true}, {name: 'create', label: 'Create pipe', enabled: true, status: 'available', runtimeRequired: true}, {name: 'delete', label: 'Delete pipe', enabled: true, status: 'available', runtimeRequired: true}, {name: 'inspect', label: 'Inspect pipe', enabled: true, status: 'available', runtimeRequired: true}, {name: 'start', label: 'Start pipe', enabled: true, status: 'available', runtimeRequired: true}, {name: 'stop', label: 'Stop pipe', enabled: true, status: 'available', runtimeRequired: true}, ], }, filters: pipeFilters, columns: pipeColumns, } } export function pipesSchemaFor(cloud: CloudProvider): ServiceSchema | null { return cloud === 'aws' ? awsPipesSchema() : null }