Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] main from labring:main #641

Merged
merged 1 commit into from
Sep 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14,426 changes: 8,328 additions & 6,098 deletions frontend/pnpm-lock.yaml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions frontend/providers/applaunchpad/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"ansi_up": "^5.2.1",
"axios": "^1.4.0",
"dayjs": "^1.11.9",
"dns": "^0.2.2",
"echarts": "^5.4.3",
"fast-json-patch": "^3.1.1",
"framer-motion": "^9.1.7",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
"Protocol": "Protocol",
"Export Domain": " Domain",
"Custom Domain": "Custom Domain",
"Please CNAME your custom domain to": "Please CNAME your custom domain to",
"CNAME Tips": "Please go to your domain name service provider, add the domain name 'CNAME' resolution to {{domain}}, after the resolution takes effect, you can bind your own domain name.",
"Option": "Option",
"Run command": "Command",
"Command parameters": "Parameters",
Expand Down
17 changes: 14 additions & 3 deletions frontend/providers/applaunchpad/public/locales/zh/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"memory": "内存",
"storage": "存储卷",
"gpu": "GPU",
"Port": "端口",
"Applications": "应用列表",
"Create Application": "新建应用",
"Cancel": "取消",
Expand Down Expand Up @@ -33,7 +34,7 @@
"Command": "启动命令",
"Parameters": "运行参数",
"Not Configured": "未配置",
"Open Public Access": "可外网访问",
"Open Public Access": "外网访问",
"Configuration File": "配置文件",
"Storage": "存储卷",
"Environment Variables": "环境变量",
Expand Down Expand Up @@ -70,7 +71,7 @@
"jump_message": "该应用不允许单独使用,点击确认前往 Sealos Desktop 使用。",
"pause_message": "请注意,暂停状态下无法变更应用,并且如果您使用了存储卷,存储券仍会收费,请确认!",
"Confirm to restart this application?": "确认重启该应用?",
"You haven't created any application yet.": "您还没有新建应用",
"You haven't created any application yet.": "您还没有新建应用",
"Confirm deletion": "确认删除",
"Deletion warning": "删除警告",
"Are you sure you want to delete this application? If you proceed, all data for this project will be deleted.": "如果确认要删除这个应用吗?如果执行此操作,将删除该项目的所有数据。",
Expand Down Expand Up @@ -107,7 +108,11 @@
"Protocol": "协议",
"Export Domain": "出口域名",
"Custom Domain": "自定义域名",
"Please CNAME your custom domain to": "请将您的自定义域名 cname 到",
"CNAME Tips": "请到您的域名服务商处,添加该域名的 `CNAME` 解析到 {{domain}},解析生效后即可绑定自定义域名。",
"Custom Domain Error": "添加自定义域名失败,请检查是否已经 CName。",
"Copy Domain Success": "复制域名成功",
"Public Access": "外网访问",
"Network port conflict": "容器端口重复",
"Option": "选填",
"Run command": "运行命令",
"Command parameters": "命令参数",
Expand Down Expand Up @@ -175,6 +180,12 @@
"The minimum number of instances is 1": "实例数最小为1",
"The maximum number of instances is 20": "实例数最大为20",
"Amount": "数量",
"Input your custom domain": "输入你的域名",
"Cname auth error: customDomain's cname is not equal to publicDomain": "CName 校验错误,你需要先 CName 到指定域名才能绑定",
"If no, the default command is used": "不填则为默认命令",
"Add Port": "添加端口",
"Copy": "复制",
"Open Link": "打开链接",
"app": {
"Resource Quota": "资源配额",
"The applied CPU exceeds the quota": "申请的 CPU 超出限制,请联系管理员",
Expand Down
4 changes: 4 additions & 0 deletions frontend/providers/applaunchpad/src/api/params.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type AuthCnamePrams = {
publicDomain: string;
customDomain: string;
};
5 changes: 4 additions & 1 deletion frontend/providers/applaunchpad/src/api/platform.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { GET } from '@/services/request';
import { GET, POST } from '@/services/request';
import type { Response as InitDataType } from '@/pages/api/platform/getInitData';
import type { UserQuotaItemType, userPriceType } from '@/types/user';
import { AuthCnamePrams } from './params';

export const getResourcePrice = () => GET<userPriceType>('/api/platform/resourcePrice');
export const getInitData = () => GET<InitDataType>('/api/platform/getInitData');
Expand All @@ -9,3 +10,5 @@ export const getUserQuota = () =>
balance: number;
quota: UserQuotaItemType[];
}>('/api/platform/getQuota');

export const postAuthCname = (data: AuthCnamePrams) => POST('/api/platform/authCname', data);
54 changes: 54 additions & 0 deletions frontend/providers/applaunchpad/src/components/MyModal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';
import {
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalCloseButton,
ModalContentProps,
Box
} from '@chakra-ui/react';

interface Props extends ModalContentProps {
showCloseBtn?: boolean;
title?: any;
isCentered?: boolean;
isOpen: boolean;
onClose: () => void;
}

const MyModal = ({
isOpen,
onClose,
title,
children,
showCloseBtn = true,
isCentered,
w = 'auto',
maxW = ['90vw', '600px'],
...props
}: Props) => {
return (
<Modal isOpen={isOpen} onClose={onClose} autoFocus={false} isCentered={isCentered}>
<ModalOverlay />
<ModalContent
display={'flex'}
flexDirection={'column'}
w={w}
minW={['90vw', '400px']}
maxW={maxW}
position={'relative'}
maxH={'90vh'}
{...props}
>
{!!title && <ModalHeader>{title}</ModalHeader>}
<Box overflow={'overlay'} h={'100%'}>
{showCloseBtn && <ModalCloseButton />}
{children}
</Box>
</ModalContent>
</Modal>
);
};

export default MyModal;
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,11 @@ export const codeTheme = {
},
'hljs-strong': {
fontWeight: 'bold'
}
},
'-webkit-touch-callout': 'none' /* iOS Safari */,
'-webkit-user-select': 'none' /* Safari */,
'-khtml-user-select': 'none' /* Konqueror HTML */,
'-moz-user-select': 'none' /* Old versions of Firefox */,
'-ms-user-select': 'none' /* Internet Explorer/Edge */,
'user-select': 'none' /* Non-prefixed version, currently supported by Chrome, Opera and Firefox */
};
8 changes: 7 additions & 1 deletion frontend/providers/applaunchpad/src/constants/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,18 @@ export const podStatusMap = {
}
};

export const ProtocolList = [
{ value: 'HTTP', label: 'https://' },
{ value: 'GRPC', label: 'grpcs://' },
{ value: 'WS', label: 'wss://' }
];

export const noGpuSliderKey = 'NoGpu';
export const pauseKey = 'deploy.cloud.sealos.io/pause';
export const maxReplicasKey = 'deploy.cloud.sealos.io/maxReplicas';
export const minReplicasKey = 'deploy.cloud.sealos.io/minReplicas';
export const appDeployKey = 'cloud.sealos.io/app-deploy-manager';
export const domainKey = `cloud.sealos.io/app-deploy-manager-domain`;
export const publicDomainKey = `cloud.sealos.io/app-deploy-manager-domain`;
export const gpuNodeSelectorKey = 'nvidia.com/gpu.product';
export const gpuResourceKey = 'nvidia.com/gpu';
export enum Coin {
Expand Down
20 changes: 13 additions & 7 deletions frontend/providers/applaunchpad/src/constants/editApp.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import type { AppEditType } from '@/types/app';
import { customAlphabet } from 'nanoid';
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz', 12);

export const editModeMap = (isEdit: boolean) => {
if (isEdit) {
Expand Down Expand Up @@ -28,13 +30,17 @@ export const defaultEditVal: AppEditType = {
replicas: 1,
cpu: 100,
memory: 64,
containerOutPort: 80,
accessExternal: {
use: false,
backendProtocol: 'HTTP',
outDomain: '',
selfDomain: ''
},
networks: [
{
networkName: '',
portName: nanoid(),
port: 80,
protocol: 'HTTP',
openPublicDomain: false,
publicDomain: '',
customDomain: ''
}
],
envs: [],
hpa: {
use: false,
Expand Down
5 changes: 5 additions & 0 deletions frontend/providers/applaunchpad/src/constants/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ const Button = defineStyleConfig({
baseStyle: {
_active: {
transform: 'scale(0.98)'
},
_disabled: {
_hover: {
bg: 'myGray.900 !important'
}
}
},
sizes: {
Expand Down
36 changes: 36 additions & 0 deletions frontend/providers/applaunchpad/src/hooks/useRequest.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { useToast } from '@/hooks/useToast';
import { useMutation } from '@tanstack/react-query';
import type { UseMutationOptions } from '@tanstack/react-query';
import { getErrText } from '@/utils/tools';
import { useTranslation } from 'react-i18next';

interface Props extends UseMutationOptions<any, any, any, any> {
successToast?: string | null;
errorToast?: string | null;
}

export const useRequest = ({ successToast, errorToast, onSuccess, onError, ...props }: Props) => {
const { toast } = useToast();
const { t } = useTranslation();
const mutation = useMutation<unknown, unknown, any, unknown>({
...props,
onSuccess(res, variables: void, context: unknown) {
onSuccess?.(res, variables, context);
successToast &&
toast({
title: successToast,
status: 'success'
});
},
onError(err: any, variables: void, context: unknown) {
onError?.(err, variables, context);
errorToast &&
toast({
title: t(getErrText(err, errorToast)),
status: 'error'
});
}
});

return mutation;
};
21 changes: 14 additions & 7 deletions frontend/providers/applaunchpad/src/mock/apps.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { AppListItemType, AppDetailType, PodDetailType } from '@/types/app';
import { appStatusMap, podStatusMap } from '@/constants/app';
import { customAlphabet } from 'nanoid';
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz', 12);

export const MOCK_APPS: AppListItemType[] = [
{
id: 'string',
Expand Down Expand Up @@ -296,13 +299,17 @@ export const MOCK_APP_DETAIL: AppDetailType = {
memory: 0,
usedCpu: new Array(30).fill(0),
usedMemory: new Array(30).fill(0),
containerOutPort: 8000,
accessExternal: {
use: true,
backendProtocol: 'HTTP',
outDomain: '',
selfDomain: ''
},
networks: [
{
networkName: '',
portName: nanoid(),
port: 80,
protocol: 'HTTP',
openPublicDomain: false,
publicDomain: '',
customDomain: ''
}
],
envs: [],
hpa: {
use: false,
Expand Down
11 changes: 10 additions & 1 deletion frontend/providers/applaunchpad/src/pages/api/delApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ApiResp } from '@/services/kubernet';
import { authSession } from '@/services/backend/auth';
import { getK8s } from '@/services/backend/kubernetes';
import { jsonRes } from '@/services/backend/response';
import { appDeployKey } from '@/constants/app';

export default async function handler(req: NextApiRequest, res: NextApiResponse<ApiResp>) {
try {
Expand All @@ -21,7 +22,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
k8sCore.deleteNamespacedService(name, namespace), // delete service
k8sCore.deleteNamespacedConfigMap(name, namespace), // delete configMap
k8sCore.deleteNamespacedSecret(name, namespace), // delete secret
k8sNetworkingApp.deleteNamespacedIngress(name, namespace), // delete Ingress
k8sNetworkingApp.deleteCollectionNamespacedIngress(
namespace,
undefined,
undefined,
undefined,
undefined,
undefined,
`${appDeployKey}=${name}`
), // delete Ingress
k8sCustomObjects.deleteNamespacedCustomObject(
// delete Issuer
'cert-manager.io',
Expand Down
21 changes: 19 additions & 2 deletions frontend/providers/applaunchpad/src/pages/api/getAppByAppName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ApiResp } from '@/services/kubernet';
import { authSession } from '@/services/backend/auth';
import { getK8s } from '@/services/backend/kubernetes';
import { jsonRes } from '@/services/backend/response';
import { appDeployKey } from '@/constants/app';

export default async function handler(req: NextApiRequest, res: NextApiResponse<ApiResp>) {
try {
Expand All @@ -20,7 +21,22 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
k8sApp.readNamespacedStatefulSet(appName, namespace),
k8sCore.readNamespacedService(appName, namespace),
k8sCore.readNamespacedConfigMap(appName, namespace),
k8sNetworkingApp.readNamespacedIngress(appName, namespace),
k8sNetworkingApp
.listNamespacedIngress(
namespace,
undefined,
undefined,
undefined,
undefined,
`${appDeployKey}=${appName}`
)
.then((res) => ({
body: res.body.items.map((item) => ({
...item,
apiVersion: res.body.apiVersion, // item does not contain apiversion and kind
kind: 'Ingress'
}))
})),
k8sCore.readNamespacedSecret(appName, namespace),
k8sAutoscaling.readNamespacedHorizontalPodAutoscaler(appName, namespace)
]);
Expand All @@ -32,7 +48,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
if (+item.reason?.body?.code === 404) return '';
throw new Error('Get APP Deployment Error');
})
.filter((item) => item);
.filter((item) => item)
.flat();

jsonRes(res, {
data: responseData
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@/services/backend/response';
import dns from 'dns';
import type { AuthCnamePrams } from '@/api/params';
import { getErrText } from '@/utils/tools';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const { publicDomain, customDomain } = req.body as AuthCnamePrams;

await (async () =>
new Promise((resolve, reject) => {
dns.resolveCname(customDomain, (err, address) => {
if (err) return reject(err);

if (address[0] !== publicDomain)
return reject("Cname auth error: customDomain's cname is not equal to publicDomain");
resolve('');
});
}))();

jsonRes(res);
} catch (error) {
jsonRes(res, {
code: 500,
error
});
}
}
Loading
Loading