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

feat:template draft & default random #3973

Merged
merged 3 commits into from Sep 23, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -33,8 +33,8 @@ Sealos['siːləs] is a cloud operating system distribution based on the Kubernet

[Try online demo](https://cloud.sealos.io)

* [Easily Deploy Nginx in 30 Seconds on Sealos](https://sealos.io/docs/quick-start/install-apps-with-app-launchpad)
* [Start a mysql/pgsql/mongo highly available database in 30 seconds on Sealos](https://sealos.io/docs/quick-start/install-db-with-database)
* [Easily Deploy Nginx in 30 Seconds on Sealos](https://sealos.io/docs/quick-start/app-deployments/use-app-launchpad)
* [Start a mysql/pgsql/mongo highly available database in 30 seconds on Sealos](https://sealos.io/docs/quick-start/app-deployments/install-db-with-database)
* [Running WordPress on Sealos](https://sealos.io/docs/examples/blog-platform/install-wordpress)
* [Running the Uptime Kuma dial test system on Sealos](https://docs.sealos.io/docs/examples/dial-testing-system/install-uptime-kuma)
* [Running a low-code platform on Sealos](https://docs.sealos.io/docs/category/low-code-platform)
Expand Down
4 changes: 2 additions & 2 deletions README_zh.md
Expand Up @@ -34,8 +34,8 @@ Sealos 是一款以 Kubernetes 为内核的**云操作系统发行版**。它以

[在线使用](https://cloud.sealos.io)

* [在 Sealos 上 30 秒内轻松部署 Nginx](https://sealos.io/docs/quick-start/install-apps-with-app-launchpad)
* [在 Sealos 上 30 秒启动 mysql/pgsql/mongo 高可用数据库](https://sealos.io/docs/quick-start/install-db-with-database)
* [在 Sealos 上 30 秒内轻松部署 Nginx](https://sealos.io/docs/quick-start/app-deployments/use-app-launchpad)
* [在 Sealos 上 30 秒启动 mysql/pgsql/mongo 高可用数据库](https://sealos.io/docs/quick-start/app-deployments/install-db-with-database)
* [在 Sealos 上 运行 WordPress](https://sealos.io/docs/examples/blog-platform/install-wordpress)
* [在 Sealos 上 运行 Uptime Kuma 拨测系统](https://sealos.io/docs/examples/dial-testing-system/install-uptime-kuma)
* [在 Sealos 上 运行低代码平台](https://sealos.io/docs/category/low-code-platform)
Expand Down
24 changes: 12 additions & 12 deletions frontend/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/providers/template/package.json
Expand Up @@ -18,7 +18,7 @@
"@kubernetes/client-node": "^0.18.1",
"@next/font": "13.1.6",
"@tanstack/react-query": "^4.24.10",
"@uiw/react-codemirror": "^4.21.9",
"@uiw/react-codemirror": "4.21.17",
"axios": "^1.3.4",
"dayjs": "^1.11.7",
"echarts": "^5.4.3",
Expand Down
4 changes: 4 additions & 0 deletions frontend/providers/template/public/locales/en/common.json
Expand Up @@ -156,5 +156,9 @@
"YAML File": "YAML File",
"Template Development": "Template Development",
"Dryrun Deploy": "Dryrun Deploy"
},
"SideBar": {
"Applications": "Applications",
"My App": "My App"
}
}
4 changes: 4 additions & 0 deletions frontend/providers/template/public/locales/zh/common.json
Expand Up @@ -162,5 +162,9 @@
"YAML File": "YAML 文件",
"Template Development": "模板开发",
"Dryrun Deploy": "试运行部署"
},
"SideBar": {
"Applications": "所有应用",
"My App": "我的应用"
}
}
3 changes: 3 additions & 0 deletions frontend/providers/template/src/api/app.ts
Expand Up @@ -4,3 +4,6 @@ export const postDeployApp = (yamlList: string[], type: 'create' | 'replace' | '
POST('/api/applyApp', { yamlList, type });

export const getTemplate = (templateName: string) => POST('/api/getTemplate', { templateName });

export const getKindTemplate = (templateName: string) =>
POST('/api/getKindTemplate', { templateName });
4 changes: 2 additions & 2 deletions frontend/providers/template/src/pages/404.tsx
Expand Up @@ -4,10 +4,10 @@ import { useRouter } from 'next/router';
const NonePage = () => {
const router = useRouter();
useEffect(() => {
router.push('/deploy');
router.push('/');
}, [router]);

return <div></div>;
return null;
};

export default NonePage;
2 changes: 0 additions & 2 deletions frontend/providers/template/src/pages/_app.tsx
Expand Up @@ -127,8 +127,6 @@ const App = ({ Component, pageProps, domain }: AppProps & { domain: string }) =>
<QueryClientProvider client={queryClient}>
<ChakraProvider theme={theme}>
<Component {...pageProps} />
{/* <ConfirmChild /> */}
{/* <Loading loading={loading} /> */}
</ChakraProvider>
</QueryClientProvider>
</>
Expand Down
8 changes: 4 additions & 4 deletions frontend/providers/template/src/pages/api/applyApp.ts
Expand Up @@ -10,13 +10,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
type: 'create' | 'replace' | 'dryrun';
};

if (!yamlList || yamlList.length < 2) {
jsonRes(res, {
if (!yamlList) {
return jsonRes(res, {
code: 500,
error: 'params error'
error: 'yaml list is empty'
});
return;
}

try {
const { applyYamlList } = await getK8s({
kubeconfig: await authSession(req.headers)
Expand Down
45 changes: 45 additions & 0 deletions frontend/providers/template/src/pages/api/getKindTemplate.ts
@@ -0,0 +1,45 @@
import { authSession } from '@/services/backend/auth';
import { getK8s } from '@/services/backend/kubernetes';
import { jsonRes } from '@/services/backend/response';
import { ApiResp } from '@/services/kubernet';
import { TemplateType } from '@/types/app';
import { getTemplateDataSource } from '@/utils/json-yaml';
import fs from 'fs';
import yaml from 'js-yaml';
import type { NextApiRequest, NextApiResponse } from 'next';
import path from 'path';

export default async function handler(req: NextApiRequest, res: NextApiResponse<ApiResp>) {
try {
const { templateName } = req.body;
let user_namespace = '';

try {
const { namespace } = await getK8s({
kubeconfig: await authSession(req.headers)
});
user_namespace = namespace;
} catch (error) {
console.log(error, 'errpr-');
}

const originalPath = process.cwd();
const targetPath = path.resolve(originalPath, 'FastDeployTemplates', 'template');
const yamlString = fs.readFileSync(`${targetPath}/${templateName}.yaml`, 'utf-8');
const yamlData = yaml.loadAll(yamlString);
const templateYaml: TemplateType = yamlData.find(
(item: any) => item.kind === 'Template'
) as TemplateType;

jsonRes(res, {
code: 200,
data: templateYaml
});
} catch (err: any) {
console.log(err);
jsonRes(res, {
code: 500,
error: err
});
}
}
7 changes: 5 additions & 2 deletions frontend/providers/template/src/pages/api/listTemplate.ts
@@ -1,5 +1,6 @@
import { jsonRes } from '@/services/backend/response';
import { ApiResp } from '@/services/kubernet';
import { TemplateType } from '@/types/app';
import fs from 'fs';
import type { NextApiRequest, NextApiResponse } from 'next';
import path from 'path';
Expand All @@ -11,8 +12,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
try {
if (fs.existsSync(jsonPath)) {
const jsonData = fs.readFileSync(jsonPath, 'utf8');
const objects = JSON.parse(jsonData);
return jsonRes(res, { data: objects, code: 200 });
const _templates: TemplateType[] = JSON.parse(jsonData);
console.log(_templates?.length, 'templates length');
const templates = _templates.filter((item) => item?.spec?.draft !== true);
return jsonRes(res, { data: templates, code: 200 });
} else {
return jsonRes(res, { data: [], code: 200 });
}
Expand Down
17 changes: 11 additions & 6 deletions frontend/providers/template/src/pages/api/updateRepo.ts
Expand Up @@ -39,13 +39,18 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
const jsonPath = path.resolve(originalPath, 'fast_deploy_template.json');

try {
if (!fs.existsSync(targetPath)) {
await execAsync(`git clone --depth 1 ${repoHttpUrl} ${targetPath}`);
} else {
await execAsync(`cd ${targetPath} && git pull`);
}
const timeoutPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('operation timed out'));
}, 30 * 1000);
});
const gitOperationPromise = !fs.existsSync(targetPath)
? execAsync(`git clone --depth 1 ${repoHttpUrl} ${targetPath}`)
: execAsync(`cd ${targetPath} && git pull`);

await Promise.race([gitOperationPromise, timeoutPromise]);
} catch (error) {
console.error(error);
return jsonRes(res, { error: 'git operation timed out', code: 500 });
}

if (!fs.existsSync(targetPath)) {
Expand Down
19 changes: 8 additions & 11 deletions frontend/providers/template/src/pages/deploy/index.tsx
@@ -1,4 +1,4 @@
import { getTemplate, postDeployApp } from '@/api/app';
import { getKindTemplate, getTemplate, postDeployApp } from '@/api/app';
import MyIcon from '@/components/Icon';
import { editModeMap } from '@/constants/editApp';
import { useConfirm } from '@/hooks/useConfirm';
Expand Down Expand Up @@ -50,12 +50,10 @@ const EditApp = ({ appName, tabType }: { appName?: string; tabType: string }) =>
[templateSource]
);

const { data: FastDeployTemplates } = useQuery(['cloneTemplte'], () => GET('/api/listTemplate'));

const { data: platformEnvs } = useQuery(['getPlatformEnvs'], () => GET('/api/platform/getEnv'));

const templateDetail: TemplateType = FastDeployTemplates?.find(
(item: TemplateType) => item?.metadata?.name === templateName
const { data: templateDetail } = useQuery(['getKindTemplate', templateName], () =>
getKindTemplate(templateName)
);

const { openConfirm, ConfirmChild } = useConfirm({
Expand Down Expand Up @@ -204,6 +202,8 @@ const EditApp = ({ appName, tabType }: { appName?: string; tabType: string }) =>
return null;
}
const res: TemplateSource = await getTemplate(templateName);
console.log(res);

setTemplateSource(res);
try {
const yamlString = res.yamlList?.map((item) => JSYAML.dump(item)).join('---\n');
Expand Down Expand Up @@ -246,8 +246,7 @@ const EditApp = ({ appName, tabType }: { appName?: string; tabType: string }) =>
justifyContent={'start'}
alignItems={'center'}
backgroundColor={'rgba(255, 255, 255)'}
backdropBlur={'100px'}
>
backdropBlur={'100px'}>
<Box cursor={'pointer'} onClick={() => router.push('/')}>
<MyIcon ml={'46px'} name="arrowLeft" color={'#24282C'} w={'16px'} h={'16px'}></MyIcon>
</Box>
Expand All @@ -256,8 +255,7 @@ const EditApp = ({ appName, tabType }: { appName?: string; tabType: string }) =>
fontWeight={500}
fontSize={16}
textDecoration={'none'}
color={'#7B838B'}
>
color={'#7B838B'}>
<BreadcrumbItem textDecoration={'none'}>
<BreadcrumbLink _hover={{ color: '#219BF4', textDecoration: 'none' }} href="/">
{t('Template List')}
Expand All @@ -276,8 +274,7 @@ const EditApp = ({ appName, tabType }: { appName?: string; tabType: string }) =>
flexDirection={'column'}
width={'100%'}
flexGrow={1}
backgroundColor={'rgba(255, 255, 255, 0.90)'}
>
backgroundColor={'rgba(255, 255, 255, 0.90)'}>
<Header
templateDetail={templateDetail}
appName={''}
Expand Down
17 changes: 6 additions & 11 deletions frontend/providers/template/src/pages/develop/index.tsx
Expand Up @@ -132,7 +132,7 @@ export default function Develop() {
description: result?.toString()
});
} catch (error) {
console.log(error, 'sadasdas');
console.log(error, '===apply err===');

setErrorMessage(JSON.stringify(error));
}
Expand Down Expand Up @@ -182,8 +182,7 @@ export default function Develop() {
borderRadius={'8px'}
overflowY={'hidden'}
overflowX={'scroll'}
flex={1}
>
flex={1}>
{/* left */}
<Flex flexDirection={'column'} w="50%" borderRight={'1px solid #EFF0F1'}>
<Flex
Expand All @@ -193,8 +192,7 @@ export default function Develop() {
alignItems={'center'}
backgroundColor={'#F8FAFB'}
px="36px"
borderRadius={'8px 8px 0px 0px '}
>
borderRadius={'8px 8px 0px 0px '}>
<MyIcon name="dev" color={'#24282C'} w={'24px'} h={'24px'}></MyIcon>
<Text fontWeight={'500'} fontSize={'16px'} color={'#24282C'} ml="8px">
{t('develop.Development')}
Expand Down Expand Up @@ -222,8 +220,7 @@ export default function Develop() {
alignItems={'center'}
backgroundColor={'#F8FAFB'}
pl="42px"
borderRadius={'8px 8px 0px 0px '}
>
borderRadius={'8px 8px 0px 0px '}>
<MyIcon name="eyeShow" color={'#24282C'} w={'24px'} h={'24px'}></MyIcon>
<Text fontWeight={'500'} fontSize={'16px'} color={'#24282C'} ml="8px">
{t('develop.Preview')}
Expand All @@ -235,8 +232,7 @@ export default function Develop() {
pt="26px"
pr={{ sm: '20px', md: '60px' }}
borderBottom={'1px solid #EFF0F1'}
flexDirection={'column'}
>
flexDirection={'column'}>
<Text fontWeight={'500'} fontSize={'18px'} color={'#24282C'}>
{t('develop.Configure Form')}
</Text>
Expand All @@ -252,8 +248,7 @@ export default function Develop() {
minW={'100px'}
h={'34px'}
variant={'link'}
onClick={handleExportYaml}
>
onClick={handleExportYaml}>
{t('Export')} Yaml
</Button>
</Flex>
Expand Down