diff --git a/src/handlers/provision.ts b/src/handlers/provision.ts index 6248d11..ff223f8 100644 --- a/src/handlers/provision.ts +++ b/src/handlers/provision.ts @@ -338,6 +338,38 @@ export async function handleGetBalance( } } +/** + * GET /api/provision/images + * Get available OS images + */ +export async function handleGetOsImages( + env: Env, + corsHeaders: Record +): Promise { + try { + const provisioningService = new ProvisioningService( + env, + env.DB, + env.USER_DB + ); + + const images = await provisioningService.getOsImages(); + + // Return simplified image list for API consumers + const response = images.map((img) => ({ + key: img.key, + name: img.name, + family: img.family, + is_default: img.is_default === 1, + })); + + return createSuccessResponse({ images: response }, 200, corsHeaders); + } catch (error) { + console.error('[handleGetOsImages] Error:', error); + return createErrorResponse('Internal server error', 500, undefined, corsHeaders); + } +} + /** * Map error codes to HTTP status codes */ diff --git a/src/index.ts b/src/index.ts index e0eba10..bc1b75a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,6 +16,7 @@ import { handleGetOrder, handleDeleteOrder, handleGetBalance, + handleGetOsImages, } from './handlers/provision'; import { handleProvisionQueue } from './handlers/queue'; import type { ProvisionQueueMessage } from './types'; @@ -113,6 +114,10 @@ export default { return handleGetBalance(request, env, corsHeaders); } + if (path === '/api/provision/images' && request.method === 'GET') { + return handleGetOsImages(env, corsHeaders); + } + // Dynamic route: /api/provision/orders/:id const orderMatch = path.match(/^\/api\/provision\/orders\/([a-zA-Z0-9-]+)$/); if (orderMatch) { diff --git a/src/services/provisioning-service.ts b/src/services/provisioning-service.ts index d2c0c2b..2909580 100644 --- a/src/services/provisioning-service.ts +++ b/src/services/provisioning-service.ts @@ -371,6 +371,13 @@ export class ProvisioningService { return { balance_krw: balance, user_id: user.id }; } + /** + * Get available OS images + */ + async getOsImages() { + return this.repo.getActiveOsImages(); + } + /** * Delete a server (terminate) - requires telegram_id for authorization */