Skip to content

Commit

Permalink
fix:dbprovider auto backup (#4515)
Browse files Browse the repository at this point in the history
* fix:dbprovider auto backup

Signed-off-by: jingyang <3161362058@qq.com>

* delete BundleAnalyzerPlugin

---------

Signed-off-by: jingyang <3161362058@qq.com>
  • Loading branch information
zjy365 committed Feb 2, 2024
1 parent deb1491 commit 6727ced
Show file tree
Hide file tree
Showing 13 changed files with 149 additions and 111 deletions.
16 changes: 7 additions & 9 deletions frontend/providers/applaunchpad/next.config.js
@@ -1,8 +1,6 @@
/** @type {import('next').NextConfig} */
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const { i18n } = require('./next-i18next.config');
const analyzer = process.env === 'production' ? [new BundleAnalyzerPlugin()] : [];
const path = require('path');
const { i18n } = require('./next-i18next.config')
const path = require('path')
const nextConfig = {
i18n,
output: 'standalone',
Expand All @@ -15,14 +13,14 @@ const nextConfig = {
issuer: /\.[jt]sx?$/,
use: ['@svgr/webpack']
}
]);
config.plugins = [...config.plugins, ...analyzer];
return config;
])
config.plugins = [...config.plugins]
return config
},
transpilePackages: ['@sealos/driver'],
experimental: {
outputFileTracingRoot: path.join(__dirname, '../../')
}
};
}

module.exports = nextConfig;
module.exports = nextConfig
16 changes: 7 additions & 9 deletions frontend/providers/cronjob/next.config.js
@@ -1,8 +1,6 @@
/** @type {import('next').NextConfig} */
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const { i18n } = require('./next-i18next.config');
const analyzer = process.env === 'production' ? [new BundleAnalyzerPlugin()] : [];
const path = require('path');
const { i18n } = require('./next-i18next.config')
const path = require('path')
const nextConfig = {
i18n,
output: 'standalone',
Expand All @@ -15,14 +13,14 @@ const nextConfig = {
issuer: /\.[jt]sx?$/,
use: ['@svgr/webpack']
}
]);
config.plugins = [...config.plugins, ...analyzer];
return config;
])
config.plugins = [...config.plugins]
return config
},
experimental: {
// this includes files from the monorepo base two directories up
outputFileTracingRoot: path.join(__dirname, '../../')
}
};
}

module.exports = nextConfig;
module.exports = nextConfig
9 changes: 6 additions & 3 deletions frontend/providers/dbprovider/deploy/manifests/rbac.yaml
Expand Up @@ -9,9 +9,12 @@ kind: ClusterRole
metadata:
name: cluster-version-reader
rules:
- apiGroups: ["apps.kubeblocks.io"]
resources: [ "clusterversions" ]
verbs: [ "get", "watch", "list"]
- apiGroups: ['apps.kubeblocks.io']
resources: ['clusterversions']
verbs: ['get', 'watch', 'list']
- apiGroups: ['dataprotection.kubeblocks.io']
resources: ['backuprepos']
verbs: ['get', 'watch', 'list']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
Expand Down
16 changes: 7 additions & 9 deletions frontend/providers/dbprovider/next.config.js
@@ -1,8 +1,6 @@
/** @type {import('next').NextConfig} */
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const { i18n } = require('./next-i18next.config');
const analyzer = process.env === 'production' ? [new BundleAnalyzerPlugin()] : [];
const path = require('path');
const { i18n } = require('./next-i18next.config')
const path = require('path')
const nextConfig = {
i18n,
output: 'standalone',
Expand All @@ -15,14 +13,14 @@ const nextConfig = {
issuer: /\.[jt]sx?$/,
use: ['@svgr/webpack']
}
]);
config.plugins = [...config.plugins, ...analyzer];
return config;
])
config.plugins = [...config.plugins]
return config
},
experimental: {
// this includes files from the monorepo base two directories up
outputFileTracingRoot: path.join(__dirname, '../../')
}
};
}

module.exports = nextConfig;
module.exports = nextConfig
60 changes: 49 additions & 11 deletions frontend/providers/dbprovider/src/pages/api/backup/updatePolicy.ts
@@ -1,28 +1,33 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { ApiResp } from '@/services/kubernet';
import { DBTypeEnum } from '@/constants/db';
import { authSession } from '@/services/backend/auth';
import { getK8s } from '@/services/backend/kubernetes';
import { K8sApi, K8sApiDefault, getK8s } from '@/services/backend/kubernetes';
import { jsonRes } from '@/services/backend/response';
import { ApiResp } from '@/services/kubernet';
import { BackupRepoCRItemType } from '@/types/backup';
import * as k8s from '@kubernetes/client-node';
import { PatchUtils } from '@kubernetes/client-node';
import { DBBackupPolicyNameMap, DBTypeEnum } from '@/constants/db';
import type { NextApiRequest, NextApiResponse } from 'next';

export type Props = {
dbName: string;
dbType: `${DBTypeEnum}`;
patch: Object;
autoBackup?: {
enabled: boolean;
cronExpression: string;
method: string;
retentionPeriod: string;
repoName: string;
};
};

export default async function handler(req: NextApiRequest, res: NextApiResponse<ApiResp>) {
const { dbName, dbType, patch } = req.body as Props;
const { dbName, dbType, autoBackup } = req.body as Props;

console.log(dbName, dbType, patch);

if (!dbName || !dbType || !patch) {
jsonRes(res, {
if (!dbName || !dbType) {
return jsonRes(res, {
code: 500,
error: 'params error'
});
return;
}

const group = 'apps.kubeblocks.io';
Expand All @@ -34,6 +39,39 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
kubeconfig: await authSession(req)
});

// Get cluster backup repository
const kc = K8sApiDefault();
const backupRepos = (await kc
.makeApiClient(k8s.CustomObjectsApi)
.listClusterCustomObject('dataprotection.kubeblocks.io', 'v1alpha1', 'backuprepos')) as {
body: {
items: BackupRepoCRItemType[];
};
};
const backupRepoName = backupRepos?.body?.items?.[0]?.metadata?.name;

if (!backupRepoName) {
throw new Error('Missing backup repository');
}
const patch = autoBackup
? [
{
op: 'replace',
path: '/spec/backup',
value: {
...autoBackup,
repoName: backupRepoName
}
}
]
: [
{
op: 'replace',
path: '/spec/backup/enabled',
value: false
}
];

// get backup backupolicies.dataprotection.kubeblocks.io
const result = await k8sCustomObjects.patchNamespacedCustomObject(
group,
Expand Down
Expand Up @@ -45,7 +45,7 @@ const AppBaseInfo = ({ db = defaultDBDetail }: { db: DBDetailType }) => {
const { toast } = useToast();

const supportConnectDB = useMemo(() => {
return !!['postgresql', 'mongodb', 'apecloud-mysql', 'redis'].find(
return !!['postgresql', 'mongodb', 'apecloud-mysql', 'redis', 'milvus'].find(
(item) => item === db.dbType
);
}, [db.dbType]);
Expand Down Expand Up @@ -276,29 +276,33 @@ const AppBaseInfo = ({ db = defaultDBDetail }: { db: DBDetailType }) => {
color={'myGray.600'}
></MyIcon>
</Center>
<Center
ml="12px"
h="24px"
color={'#24282C'}
fontSize={'12px'}
bg="#F4F6F8"
borderRadius={'4px'}
px="8px"
cursor={'pointer'}
onClick={() => onclickConnectDB()}
>
<MyIcon name="terminal" w="16px" h="16px" />
{t('Direct Connection')}
</Center>
<Center fontSize={'12px'} fontWeight={400} ml="auto">
<Text> {t('External Network')} </Text>
<Switch
ml="8px"
size="sm"
isChecked={isChecked}
onChange={(e) => (isChecked ? closeNetWorkService() : onOpen())}
/>
</Center>
{db.dbType !== 'milvus' && (
<>
<Center
ml="12px"
h="24px"
color={'#24282C'}
fontSize={'12px'}
bg="#F4F6F8"
borderRadius={'4px'}
px="8px"
cursor={'pointer'}
onClick={() => onclickConnectDB()}
>
<MyIcon name="terminal" w="16px" h="16px" />
{t('Direct Connection')}
</Center>
<Center fontSize={'12px'} fontWeight={400} ml="auto">
<Text> {t('External Network')} </Text>
<Switch
ml="8px"
size="sm"
isChecked={isChecked}
onChange={(e) => (isChecked ? closeNetWorkService() : onOpen())}
/>
</Center>
</>
)}
</Flex>
<Box
mt={3}
Expand Down
Expand Up @@ -28,7 +28,7 @@ import { useForm } from 'react-hook-form';
import type { AutoBackupFormType, AutoBackupType } from '@/types/backup';
import Tabs from '@/components/Tabs';
import MySelect from '@/components/Select';
import { DBTypeEnum } from '@/constants/db';
import { DBBackupMethodNameMap, DBTypeEnum } from '@/constants/db';

enum NavEnum {
manual = 'manual',
Expand Down Expand Up @@ -168,24 +168,18 @@ const BackupModal = ({
return `${data.minute} * * * *`;
})();

const patch = [
{
op: 'replace',
path: '/spec/backup',
value: {
enabled: data.start,
cronExpression: convertCronTime(cron, -8),
method: 'backupTool',
pitrEnabled: false,
retentionPeriod: `${data.saveTime}${data.saveType}`
}
}
];
const autoBackup = {
enabled: data.start,
cronExpression: convertCronTime(cron, -8),
method: DBBackupMethodNameMap[dbType],
retentionPeriod: `${data.saveTime}${data.saveType}`,
repoName: ''
};

return updateBackupPolicy({
dbName,
dbType,
patch
autoBackup
});
},
onSuccess() {
Expand All @@ -206,18 +200,10 @@ const BackupModal = ({

const { mutate: onclickCloseAutoBackup } = useMutation({
mutationFn: async () => {
const patch = [
{
op: 'replace',
path: '/spec/backup/enabled',
value: false
}
];

return updateBackupPolicy({
dbName,
dbType,
patch
autoBackup: undefined
});
},
onSuccess() {
Expand Down
12 changes: 9 additions & 3 deletions frontend/providers/dbprovider/src/services/backend/kubernetes.ts
Expand Up @@ -3,6 +3,13 @@ import { cpuFormatToM, memoryFormatToMi } from '@/utils/tools';
import * as k8s from '@kubernetes/client-node';
import * as yaml from 'js-yaml';

// Load default kc
export function K8sApiDefault(): k8s.KubeConfig {
const kc = new k8s.KubeConfig();
kc.loadFromDefault();
return kc;
}

export function CheckIsInCluster(): [boolean, string] {
if (
process.env.KUBERNETES_SERVICE_HOST !== undefined &&
Expand Down Expand Up @@ -89,13 +96,12 @@ export async function createYaml(
for (const spec of created) {
try {
console.log('delete:', spec.kind);
client.delete(spec);
await client.delete(spec);
} catch (error) {
error;
}
}
// console.error(error, '<=create error')
return Promise.reject(error);
return Promise.reject(error?.body || 'Create Yaml Error');
}
return created;
}
Expand Down
11 changes: 11 additions & 0 deletions frontend/providers/dbprovider/src/types/backup.d.ts
Expand Up @@ -66,3 +66,14 @@ export type AutoBackupFormType = {
saveTime: number;
saveType: string;
};

export type BackupRepoCRItemType = {
kind: 'BackupRepo';
metadata: {
annotations: Record<string, string>;
creationTimestamp: Date;
labels: Record<string, string>;
name: string;
uid: string;
};
};
1 change: 1 addition & 0 deletions frontend/providers/dbprovider/src/types/cluster.d.ts
Expand Up @@ -54,6 +54,7 @@ export interface KubeBlockClusterSpec {
cronExpression: string;
method: string;
pitrEnabled: boolean;
repoName: string;
retentionPeriod: string;
};
}
Expand Down
1 change: 0 additions & 1 deletion frontend/providers/dbprovider/src/utils/json2Yaml.ts
Expand Up @@ -660,7 +660,6 @@ export const json2CreateCluster = (data: DBEditType, backupInfo?: BackupItemType
}
]
};
console.log(map[data.dbType].map((item) => yaml.dump(item)).join('\n---\n'));

return map[data.dbType].map((item) => yaml.dump(item)).join('\n---\n');
};
Expand Down

0 comments on commit 6727ced

Please sign in to comment.