feat: EC2 UI polished + storage persisting
This commit is contained in:
@@ -620,6 +620,42 @@ export function createCloudRoutes(injectedService?: CloudProxyService) {
|
||||
})
|
||||
})
|
||||
|
||||
app.get('/: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)
|
||||
return withRuntime(c, async () => c.json(await svc(c).listEventBridgeRules(cloud, c.req.param('id'))))
|
||||
})
|
||||
|
||||
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)
|
||||
return withRuntime(c, async () => {
|
||||
const input = await c.req.json<Record<string, unknown>>()
|
||||
const rule = await svc(c).createEventBridgeRule(cloud, c.req.param('id'), {
|
||||
name: typeof input.name === 'string' ? input.name : '',
|
||||
scheduleExpression: typeof input.scheduleExpression === 'string' ? input.scheduleExpression : undefined,
|
||||
eventPattern: typeof input.eventPattern === 'string' ? input.eventPattern : undefined,
|
||||
state: input.state === 'DISABLED' ? 'DISABLED' : input.state === 'ENABLED' ? 'ENABLED' : undefined,
|
||||
description: typeof input.description === 'string' ? input.description : undefined,
|
||||
targets: Array.isArray(input.targets) ? input.targets.flatMap((target) => {
|
||||
if (!target || typeof target !== 'object' || Array.isArray(target)) return []
|
||||
const value = target as {id?: unknown; arn?: unknown}
|
||||
return typeof value.id === 'string' && typeof value.arn === 'string' ? [{id: value.id, arn: value.arn}] : []
|
||||
}) : [],
|
||||
})
|
||||
return c.json(rule, 201)
|
||||
})
|
||||
})
|
||||
|
||||
app.delete('/:cloud/services/events/resources/:id/rules/:ruleName', 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).deleteEventBridgeRule(cloud, c.req.param('id'), c.req.param('ruleName'))
|
||||
return c.json({ok: true})
|
||||
})
|
||||
})
|
||||
|
||||
app.get('/:cloud/services/serverless/resources/:id/sqs-event-source-mappings', async (c) => {
|
||||
const cloud = c.req.param('cloud') as CloudProvider
|
||||
if (cloud !== 'aws') return c.json({error: 'Unknown cloud or service'}, 404)
|
||||
@@ -867,6 +903,60 @@ export function createCloudRoutes(injectedService?: CloudProxyService) {
|
||||
})
|
||||
})
|
||||
|
||||
app.post('/:cloud/services/notifications/resources/:id/publish', 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 body = await jsonBody<{message?: unknown; subject?: unknown; messageAttributes?: unknown}>(c)
|
||||
if (typeof body.message !== 'string' || !body.message) {
|
||||
throw new ValidationError('message is required')
|
||||
}
|
||||
if (body.subject !== undefined && typeof body.subject !== 'string') {
|
||||
throw new ValidationError('subject must be a string')
|
||||
}
|
||||
if (body.messageAttributes !== undefined && !isStringRecord(body.messageAttributes)) {
|
||||
throw new ValidationError('messageAttributes must be an object of string values')
|
||||
}
|
||||
const result = await svc(c).publishNotification(cloud, c.req.param('id'), {
|
||||
message: body.message,
|
||||
...(body.subject ? {subject: body.subject} : {}),
|
||||
...(body.messageAttributes ? {messageAttributes: body.messageAttributes} : {}),
|
||||
})
|
||||
return c.json(result)
|
||||
})
|
||||
})
|
||||
|
||||
app.get('/:cloud/services/notifications/resources/:id/subscriptions', async (c) => {
|
||||
const cloud = c.req.param('cloud') as CloudProvider
|
||||
if (!isCloudProvider(cloud)) return c.json({error: 'Unknown cloud'}, 404)
|
||||
return withRuntime(c, async () => c.json(await svc(c).listSnsSubscriptions(cloud, c.req.param('id'))))
|
||||
})
|
||||
|
||||
app.post('/:cloud/services/notifications/resources/:id/subscriptions', 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 body = await jsonBody<{protocol?: unknown; endpoint?: unknown}>(c)
|
||||
if (typeof body.protocol !== 'string' || !body.protocol.trim()) throw new ValidationError('protocol is required')
|
||||
if (typeof body.endpoint !== 'string' || !body.endpoint.trim()) throw new ValidationError('endpoint is required')
|
||||
const subscription = await svc(c).createSnsSubscription(cloud, c.req.param('id'), {
|
||||
protocol: body.protocol,
|
||||
endpoint: body.endpoint,
|
||||
})
|
||||
return c.json(subscription, 201)
|
||||
})
|
||||
})
|
||||
|
||||
app.delete('/:cloud/services/notifications/resources/:id/subscriptions/:subscriptionArn', async (c) => {
|
||||
const cloud = c.req.param('cloud') as CloudProvider
|
||||
if (!isCloudProvider(cloud)) return c.json({error: 'Unknown cloud'}, 404)
|
||||
return withRuntime(c, async () => {
|
||||
await svc(c).deleteSnsSubscription(cloud, c.req.param('subscriptionArn'))
|
||||
return c.json({ok: true})
|
||||
})
|
||||
})
|
||||
|
||||
app.post('/:cloud/services/kms/resources/:id/encrypt', async (c) => {
|
||||
const cloud = c.req.param('cloud') as CloudProvider
|
||||
if (!isCloudProvider(cloud)) return c.json({error: 'Unknown cloud'}, 404)
|
||||
@@ -984,6 +1074,13 @@ function encryptionContext(value: unknown): Record<string, string> | undefined {
|
||||
return entries.length === 0 ? undefined : Object.fromEntries(entries) as Record<string, string>
|
||||
}
|
||||
|
||||
function isStringRecord(value: unknown): value is Record<string, string> {
|
||||
return typeof value === 'object'
|
||||
&& value !== null
|
||||
&& !Array.isArray(value)
|
||||
&& Object.values(value).every((item) => typeof item === 'string')
|
||||
}
|
||||
|
||||
function stringHeaders(value: unknown): Record<string, string> {
|
||||
if (value === undefined) return {}
|
||||
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
||||
|
||||
Reference in New Issue
Block a user