| gio | 3ed5959 | 2025-05-14 16:51:09 +0000 | [diff] [blame] | 1 | import axios from "axios"; |
| 2 | import { z } from "zod"; |
| 3 | |
| gio | b77cb93 | 2025-05-19 09:37:14 +0000 | [diff] [blame] | 4 | const accessSchema = z.discriminatedUnion("type", [ |
| 5 | z.object({ |
| 6 | type: z.literal("https"), |
| 7 | name: z.string(), |
| 8 | address: z.string(), |
| 9 | }), |
| 10 | z.object({ |
| 11 | type: z.literal("ssh"), |
| 12 | name: z.string(), |
| 13 | host: z.string(), |
| 14 | port: z.number(), |
| 15 | }), |
| 16 | z.object({ |
| 17 | type: z.literal("tcp"), |
| 18 | name: z.string(), |
| 19 | host: z.string(), |
| 20 | port: z.number(), |
| 21 | }), |
| 22 | z.object({ |
| 23 | type: z.literal("udp"), |
| 24 | name: z.string(), |
| 25 | host: z.string(), |
| 26 | port: z.number(), |
| 27 | }), |
| 28 | z.object({ |
| 29 | type: z.literal("postgresql"), |
| 30 | name: z.string(), |
| 31 | host: z.string(), |
| 32 | port: z.number(), |
| 33 | database: z.string(), |
| 34 | username: z.string(), |
| 35 | password: z.string(), |
| 36 | }), |
| 37 | z.object({ |
| 38 | type: z.literal("mongodb"), |
| 39 | name: z.string(), |
| 40 | host: z.string(), |
| 41 | port: z.number(), |
| 42 | database: z.string(), |
| 43 | username: z.string(), |
| 44 | password: z.string(), |
| 45 | }), |
| 46 | ]); |
| 47 | |
| gio | 3ed5959 | 2025-05-14 16:51:09 +0000 | [diff] [blame] | 48 | export const DeployResponseSchema = z.object({ |
| 49 | id: z.string(), |
| 50 | deployKey: z.string(), |
| gio | b77cb93 | 2025-05-19 09:37:14 +0000 | [diff] [blame] | 51 | access: z.array(accessSchema), |
| gio | 3ed5959 | 2025-05-14 16:51:09 +0000 | [diff] [blame] | 52 | }); |
| 53 | |
| 54 | export type DeployResponse = z.infer<typeof DeployResponseSchema>; |
| 55 | |
| 56 | export class AppManager { |
| 57 | private baseUrl: string; |
| 58 | |
| 59 | constructor(baseUrl: string = "http://appmanager.hgrz-appmanager.svc.cluster.local") { |
| 60 | this.baseUrl = baseUrl; |
| 61 | } |
| 62 | |
| 63 | async deploy(config: unknown): Promise<DeployResponse> { |
| 64 | const response = await axios.request({ |
| 65 | url: `${this.baseUrl}/api/dodo-app`, |
| 66 | method: "post", |
| 67 | data: { config }, |
| 68 | }); |
| 69 | if (response.status !== 200) { |
| 70 | throw new Error(`Failed to deploy application: ${response.statusText}`); |
| 71 | } |
| 72 | const result = DeployResponseSchema.safeParse(response.data); |
| 73 | if (!result.success) { |
| 74 | throw new Error(`Invalid deploy response format: ${result.error.message}`); |
| 75 | } |
| 76 | return result.data; |
| 77 | } |
| 78 | |
| gio | b77cb93 | 2025-05-19 09:37:14 +0000 | [diff] [blame] | 79 | async update(instanceId: string, config: unknown): Promise<DeployResponse> { |
| gio | 3ed5959 | 2025-05-14 16:51:09 +0000 | [diff] [blame] | 80 | const response = await axios.request({ |
| 81 | url: `${this.baseUrl}/api/dodo-app/${instanceId}`, |
| 82 | method: "put", |
| 83 | data: { config }, |
| 84 | }); |
| gio | b77cb93 | 2025-05-19 09:37:14 +0000 | [diff] [blame] | 85 | if (response.status !== 200) { |
| 86 | throw new Error(`Failed to update application: ${response.statusText}`); |
| 87 | } |
| 88 | const result = DeployResponseSchema.safeParse(response.data); |
| 89 | if (!result.success) { |
| 90 | throw new Error(`Invalid update response format: ${result.error.message}`); |
| 91 | } |
| 92 | return result.data; |
| gio | 3ed5959 | 2025-05-14 16:51:09 +0000 | [diff] [blame] | 93 | } |
| 94 | |
| 95 | async getStatus(instanceId: string): Promise<unknown> { |
| 96 | const response = await axios.request({ |
| 97 | url: `${this.baseUrl}/api/instance/${instanceId}/status`, |
| 98 | method: "get", |
| 99 | }); |
| 100 | if (response.status !== 200) { |
| 101 | throw new Error(`Failed to get application status: ${response.statusText}`); |
| 102 | } |
| 103 | return response.data; |
| 104 | } |
| 105 | |
| 106 | async removeInstance(instanceId: string): Promise<boolean> { |
| 107 | const response = await axios.request({ |
| 108 | url: `${this.baseUrl}/api/instance/${instanceId}/remove`, |
| 109 | method: "post", |
| 110 | }); |
| 111 | return response.status === 200; |
| 112 | } |
| 113 | } |