feat: Cloudformation + RDS

This commit is contained in:
Zakaria
2026-09-30 17:43:42 -04:00
parent 548a15d7ec
commit 7764ea0dc1
411 changed files with 10182 additions and 1063 deletions
+109 -13
View File
@@ -264,24 +264,79 @@ export function createCloudRoutes(injectedService?: CloudProxyService) {
})
})
app.get('/:cloud/services/nosql/resources/:id/items', async (c) => {
app.post('/:cloud/services/logs/resources/:id/filter', async (c) => {
const cloud = c.req.param('cloud') as CloudProvider
if (!isCloudProvider(cloud)) return c.json({error: 'Unknown cloud'}, 404)
return withRuntime(c, async () => {
const items = await svc(c).listNoSqlItems(cloud, c.req.param('id'))
return c.json(items)
const body = await c.req.json<{filterPattern?: unknown; logStreamNames?: unknown; startTime?: unknown; endTime?: unknown}>()
if (body.filterPattern !== undefined && typeof body.filterPattern !== 'string') throw new ValidationError('filterPattern must be a string.')
if (body.logStreamNames !== undefined && (!Array.isArray(body.logStreamNames) || body.logStreamNames.some((name) => typeof name !== 'string'))) throw new ValidationError('logStreamNames must be an array of strings.')
if (body.startTime !== undefined && typeof body.startTime !== 'number') throw new ValidationError('startTime must be a number (epoch milliseconds).')
if (body.endTime !== undefined && typeof body.endTime !== 'number') throw new ValidationError('endTime must be a number (epoch milliseconds).')
if (typeof body.startTime === 'number' && typeof body.endTime === 'number' && body.startTime > body.endTime) throw new ValidationError('startTime must not be after endTime.')
return c.json(await svc(c).filterLogEvents(cloud, c.req.param('id'), {
filterPattern: body.filterPattern,
logStreamNames: body.logStreamNames as string[] | undefined,
startTime: body.startTime,
endTime: body.endTime,
}, pageQuery(c)))
})
})
app.post('/:cloud/services/nosql/resources/:id/items', async (c) => {
app.post('/:cloud/services/messaging/resources/:id/messages', async (c) => {
const cloud = c.req.param('cloud') as CloudProvider
if (!isCloudProvider(cloud)) return c.json({error: 'Unknown cloud'}, 404)
if (cloud !== 'aws') return c.json({error: 'Unknown cloud or service'}, 404)
return withRuntime(c, async () => {
const document = await c.req.json<Record<string, unknown>>()
const item = await svc(c).putNoSqlItem(cloud, c.req.param('id'), document)
return c.json(item, 201)
const body = await c.req.json<{messageBody?: unknown; messageAttributes?: unknown; messageGroupId?: unknown; messageDeduplicationId?: unknown}>()
if (typeof body.messageBody !== 'string') throw new ValidationError('messageBody must be a string.')
return c.json(await svc(c).sendSqsMessage(cloud, c.req.param('id'), {
messageBody: body.messageBody,
messageAttributes: body.messageAttributes as never,
messageGroupId: typeof body.messageGroupId === 'string' ? body.messageGroupId : undefined,
messageDeduplicationId: typeof body.messageDeduplicationId === 'string' ? body.messageDeduplicationId : undefined,
}), 201)
})
})
app.post('/:cloud/services/messaging/resources/:id/messages/receive', async (c) => {
const cloud = c.req.param('cloud') as CloudProvider
if (cloud !== 'aws') return c.json({error: 'Unknown cloud or service'}, 404)
return withRuntime(c, async () => {
const body = await c.req.json<{maxNumberOfMessages?: unknown}>()
if (body.maxNumberOfMessages !== undefined && typeof body.maxNumberOfMessages !== 'number') throw new ValidationError('maxNumberOfMessages must be a number.')
return c.json(await svc(c).receiveSqsMessages(cloud, c.req.param('id'), {maxNumberOfMessages: body.maxNumberOfMessages}))
})
})
app.post('/:cloud/services/messaging/resources/:id/messages/delete', async (c) => {
const cloud = c.req.param('cloud') as CloudProvider
if (cloud !== 'aws') return c.json({error: 'Unknown cloud or service'}, 404)
return withRuntime(c, async () => {
const body = await c.req.json<{receiptHandle?: unknown}>()
if (typeof body.receiptHandle !== 'string' || !body.receiptHandle) throw new ValidationError('receiptHandle is required.')
await svc(c).deleteSqsMessage(cloud, c.req.param('id'), body.receiptHandle)
return c.json({ok: true})
})
})
app.delete('/:cloud/services/messaging/resources/:id/messages', async (c) => {
const cloud = c.req.param('cloud') as CloudProvider
if (cloud !== 'aws') return c.json({error: 'Unknown cloud or service'}, 404)
return withRuntime(c, async () => {
await svc(c).purgeSqsQueue(cloud, c.req.param('id'))
return c.json({ok: true})
})
})
app.post('/:cloud/services/messaging/resources/:id/move-tasks', async (c) => {
const cloud = c.req.param('cloud') as CloudProvider
if (cloud !== 'aws') return c.json({error: 'Unknown cloud or service'}, 404)
return withRuntime(c, async () => {
const body = await c.req.json<{destinationArn?: unknown}>()
if (body.destinationArn !== undefined && typeof body.destinationArn !== 'string') throw new ValidationError('destinationArn must be a string.')
return c.json(await svc(c).startSqsMoveTask(cloud, c.req.param('id'), {destinationArn: body.destinationArn}))
})
})
@@ -526,6 +581,8 @@ export function createCloudRoutes(injectedService?: CloudProxyService) {
const input = await c.req.json<Record<string, unknown>>()
const route = await svc(c).createApiGatewayLambdaRoute(cloud, c.req.param('id'), {
path: typeof input.path === 'string' ? input.path : '',
parentResourceId: typeof input.parentResourceId === 'string' ? input.parentResourceId : undefined,
pathPart: typeof input.pathPart === 'string' ? input.pathPart : undefined,
method: typeof input.method === 'string' ? input.method : '',
stage: typeof input.stage === 'string' ? input.stage : '',
functionName: typeof input.functionName === 'string' ? input.functionName : '',
@@ -699,6 +756,45 @@ export function createCloudRoutes(injectedService?: CloudProxyService) {
return withRuntime(c, async () => c.json(await svc(c).listEventBridgeRules(cloud, c.req.param('id'))))
})
app.post('/:cloud/services/events/resources/:id/events', async (c) => {
const cloud = c.req.param('cloud') as CloudProvider
if (cloud !== 'aws') return c.json({error: 'Unknown cloud or service'}, 404)
return withRuntime(c, async () => {
const input = await c.req.json<Record<string, unknown>>()
const result = await svc(c).putEventBridgeEvent(cloud, c.req.param('id'), {
source: typeof input.source === 'string' ? input.source : '', detailType: typeof input.detailType === 'string' ? input.detailType : '', detail: typeof input.detail === 'string' ? input.detail : '',
resources: Array.isArray(input.resources) ? input.resources.filter((resource): resource is string => typeof resource === 'string') : undefined,
})
return c.json(result, result.errorCode ? 400 : 201)
})
})
app.get('/:cloud/services/iac/resources/:id/change-sets', async (c) => {
const cloud = c.req.param('cloud') as CloudProvider
if (cloud !== 'aws') return c.json({error: 'Unknown cloud or service'}, 404)
return withRuntime(c, async () => c.json(await svc(c).listCloudFormationChangeSets(cloud, c.req.param('id'))))
})
app.post('/:cloud/services/iac/resources/:id/change-sets', async (c) => {
const cloud = c.req.param('cloud') as CloudProvider
if (cloud !== 'aws') return c.json({error: 'Unknown cloud or service'}, 404)
return withRuntime(c, async () => { const input = await c.req.json<{name?: string; templateBody?: string; parameters?: Record<string, string>; capabilities?: string[]}>(); return c.json(await svc(c).createCloudFormationChangeSet(cloud, c.req.param('id'), {name: input.name ?? '', templateBody: input.templateBody ?? '', parameters: input.parameters, capabilities: input.capabilities}), 201) })
})
app.post('/:cloud/services/iac/resources/:id/change-sets/:name/execute', async (c) => {
const cloud = c.req.param('cloud') as CloudProvider
if (cloud !== 'aws') return c.json({error: 'Unknown cloud or service'}, 404)
return withRuntime(c, async () => { await svc(c).executeCloudFormationChangeSet(cloud, c.req.param('id'), c.req.param('name')); return c.json({ok: true}) })
})
app.delete('/:cloud/services/iac/resources/:id/change-sets/:name', async (c) => {
const cloud = c.req.param('cloud') as CloudProvider
if (cloud !== 'aws') return c.json({error: 'Unknown cloud or service'}, 404)
return withRuntime(c, async () => { await svc(c).deleteCloudFormationChangeSet(cloud, c.req.param('id'), c.req.param('name')); return c.json({ok: true}) })
})
app.put('/:cloud/services/iac/resources/:id/termination-protection', async (c) => {
const cloud = c.req.param('cloud') as CloudProvider
if (cloud !== 'aws') return c.json({error: 'Unknown cloud or service'}, 404)
return withRuntime(c, async () => { const input = await c.req.json<{enabled?: boolean}>(); await svc(c).updateCloudFormationTerminationProtection(cloud, c.req.param('id'), input.enabled === true); return c.json({ok: true}) })
})
app.post('/:cloud/services/events/resources/:id/rules', async (c) => {
const cloud = c.req.param('cloud') as CloudProvider
if (cloud !== 'aws') return c.json({error: 'Unknown cloud or service'}, 404)
@@ -863,8 +959,8 @@ export function createCloudRoutes(injectedService?: CloudProxyService) {
if (!target) return c.json({error: 'Unknown cloud or service'}, 404)
return withRuntime(c, async () => {
const body = await c.req.json<{query?: string}>()
const page = await svc(c).queryCollectionItems(target.cloud, target.service, c.req.param('id'), c.req.param('cid'), body.query ?? '')
const body = await c.req.json<{query?: string | Record<string, unknown>}>()
const page = await svc(c).queryCollectionItems(target.cloud, target.service, c.req.param('id'), c.req.param('cid'), body.query ?? '', pageQuery(c))
return c.json(page)
})
})
@@ -905,8 +1001,8 @@ export function createCloudRoutes(injectedService?: CloudProxyService) {
if (!target) return c.json({error: 'Unknown cloud or service'}, 404)
return withRuntime(c, async () => {
const body = await c.req.json<{query?: string}>()
const page = await svc(c).queryFlatItems(target.cloud, target.service, c.req.param('id'), body.query ?? '')
const body = await c.req.json<{query?: string | Record<string, unknown>}>()
const page = await svc(c).queryFlatItems(target.cloud, target.service, c.req.param('id'), body.query ?? '', pageQuery(c))
return c.json(page)
})
})