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