diff --git a/frontend/providers/applaunchpad/src/pages/api/v1alpha/updateReplica.ts b/frontend/providers/applaunchpad/src/pages/api/v1alpha/updateReplica.ts new file mode 100644 index 000000000000..29563163dbbc --- /dev/null +++ b/frontend/providers/applaunchpad/src/pages/api/v1alpha/updateReplica.ts @@ -0,0 +1,101 @@ +import type { NextApiRequest, NextApiResponse } from 'next'; +import { ApiResp } from '@/services/kubernet'; +import { authSession } from '@/services/backend/auth'; +import { getK8s } from '@/services/backend/kubernetes'; +import { jsonRes } from '@/services/backend/response'; +import { pauseKey } from '@/constants/app'; + +type UpdateReplicaParams = { + appName: string; + replica: string; +}; +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + try { + const { appName, replica } = req.body as UpdateReplicaParams; + console.log(appName, replica); + + if (!appName) { + throw new Error('appName is empty'); + } + + let result; + + if (Number(replica) === 0) { + await PauseApp({ appName, replica, req }); + result = 'Application suspended successfully'; + } else { + result = 'test'; + } + + jsonRes(res, { data: result }); + } catch (err: any) { + jsonRes(res, { + code: 500, + error: err + }); + } +} + +export async function PauseApp({ + appName, + replica, + req +}: UpdateReplicaParams & { req: NextApiRequest }) { + const { apiClient, k8sAutoscaling, getDeployApp, namespace } = await getK8s({ + kubeconfig: await authSession(req.headers) + }); + + const app = await getDeployApp(appName); + if (!app.metadata?.name || !app?.metadata?.annotations || !app.spec) { + throw new Error('app data error'); + } + + // store restart data + const restartAnnotations: Record = { + target: '', + value: '' + }; + + const requestQueue: Promise[] = []; + + // check whether there are hpa + try { + const { body: hpa } = await k8sAutoscaling.readNamespacedHorizontalPodAutoscaler( + appName, + namespace + ); + restartAnnotations.target = hpa?.spec?.metrics?.[0]?.resource?.name || 'cpu'; + restartAnnotations.value = `${ + hpa?.spec?.metrics?.[0]?.resource?.target?.averageUtilization || 50 + }`; + requestQueue.push(k8sAutoscaling.deleteNamespacedHorizontalPodAutoscaler(appName, namespace)); // delete HorizontalPodAutoscaler + } catch (error: any) { + if (error?.statusCode !== 404) { + return Promise.reject('无法读取到hpa'); + } + } + + // replace source file + app.metadata.annotations[pauseKey] = JSON.stringify(restartAnnotations); + app.spec.replicas = 0; + + requestQueue.push(apiClient.replace(app)); + + return await Promise.all(requestQueue); +} + +export async function StartApp({ + appName, + replica, + req +}: UpdateReplicaParams & { req: NextApiRequest }) { + const { apiClient, getDeployApp, applyYamlList } = await getK8s({ + kubeconfig: await authSession(req.headers) + }); + + const app = await getDeployApp(appName); + + if (!app.metadata?.name || !app?.metadata?.annotations || !app.spec) { + throw new Error('app data error'); + } +} diff --git a/frontend/providers/dbprovider/public/locales/en/common.json b/frontend/providers/dbprovider/public/locales/en/common.json index 5e3bcd5a5762..de86f9a3f459 100644 --- a/frontend/providers/dbprovider/public/locales/en/common.json +++ b/frontend/providers/dbprovider/public/locales/en/common.json @@ -144,7 +144,7 @@ "Advanced Configuration": "Advanced Configuration", "Option": "Option", "Internet Migration": "Internet Migration", - "Dump Import": "Dump Import", + "File Migration": "File Migration", "Source Database": "Source Database", "Database Host": "Database Host", "DB Name": "DataBase Name", @@ -184,4 +184,4 @@ "Database UserName Empty": "Database UserName Empty", "Database Password Empty": "Database Password Empty", "Migration Failed": "Migration Failed" -} +} \ No newline at end of file diff --git a/frontend/providers/dbprovider/public/locales/zh/common.json b/frontend/providers/dbprovider/public/locales/zh/common.json index 2f63d7e4a48f..333b05118e54 100644 --- a/frontend/providers/dbprovider/public/locales/zh/common.json +++ b/frontend/providers/dbprovider/public/locales/zh/common.json @@ -187,7 +187,7 @@ "Advanced Configuration": "高级配置", "Option": "选填", "Internet Migration": "公网迁移", - "Dump Import": "Dump 导入", + "File Migration": "文件迁移", "Source Database": "源数据库", "Database Host": "数据库 Host", "DB Name": "数据库名字", @@ -224,4 +224,4 @@ "Database UserName Empty": "缺少数据库用户名", "Database Password Empty": "缺少数据库密码", "Migration Failed": "迁移失败" -} +} \ No newline at end of file diff --git a/frontend/providers/dbprovider/src/pages/db/detail/components/AppBaseInfo.tsx b/frontend/providers/dbprovider/src/pages/db/detail/components/AppBaseInfo.tsx index dcaf081cfc6b..17c121e58d10 100644 --- a/frontend/providers/dbprovider/src/pages/db/detail/components/AppBaseInfo.tsx +++ b/frontend/providers/dbprovider/src/pages/db/detail/components/AppBaseInfo.tsx @@ -44,7 +44,7 @@ const AppBaseInfo = ({ db = defaultDBDetail }: { db: DBDetailType }) => { ); }, [db.dbType]); - const { data: systemEnvs } = useQuery(['getDBSecret'], () => getAppEnv()); + const { data: systemEnvs } = useQuery(['getSystemEnvs'], () => getAppEnv()); const { data: secret } = useQuery( ['getDBSecret', db.dbName], @@ -378,12 +378,20 @@ const AppBaseInfo = ({ db = defaultDBDetail }: { db: DBDetailType }) => { {t('Billing Standards')}
- 0.05 + 0.5 / {t('Hour')}
-
+
window.open('https://forum.laf.run/d/1092')} + > - 防止用户删除数据库不完全(service没删) + 免费方案