Skip to content

Commit

Permalink
feat: template other resource
Browse files Browse the repository at this point in the history
Signed-off-by: jingyang <3161362058@qq.com>
  • Loading branch information
zjy365 committed Oct 16, 2023
1 parent 57beea9 commit 733e877
Show file tree
Hide file tree
Showing 12 changed files with 227 additions and 36 deletions.
2 changes: 1 addition & 1 deletion frontend/desktop/next-i18next.config.js
Expand Up @@ -5,7 +5,7 @@
module.exports = {
i18n: {
defaultLocale: 'en',
locales: ['en', 'zh', 'zh-Hans'],
locales: ['en', 'zh'],
localeDetection: false
}
};
3 changes: 2 additions & 1 deletion frontend/desktop/src/pages/index.tsx
Expand Up @@ -105,7 +105,8 @@ export default function Home({
}

export async function getServerSideProps({ req, res, locales }: any) {
const local = req?.cookies?.NEXT_LOCALE || 'en';
const lang: string = req?.headers?.['accept-language'] || 'zh';
const local = lang.indexOf('zh') !== -1 ? 'zh' : 'en';
const sealos_cloud_domain = process.env.SEALOS_CLOUD_DOMAIN || 'cloud.sealos.io';

return {
Expand Down
3 changes: 2 additions & 1 deletion frontend/desktop/src/pages/signin.tsx
Expand Up @@ -6,7 +6,8 @@ export default function SigninPage() {
}

export async function getServerSideProps({ req, res, locales }: any) {
const local = req?.cookies?.NEXT_LOCALE || 'en';
const lang: string = req?.headers?.['accept-language'] || 'zh';
const local = lang.indexOf('zh') !== -1 ? 'zh' : 'en';

const props = {
...(await serverSideTranslations(local, undefined, null, locales || []))
Expand Down
49 changes: 29 additions & 20 deletions frontend/providers/template/src/api/delete.ts
Expand Up @@ -22,30 +22,39 @@ export const delInstanceByName = (instanceName: string) =>
export const delJobByName = (instanceName: string) =>
DELETE('/api/resource/delJob', { instanceName });

export const deleteResourceByKind = (instanceName: string, kind: ResourceKindType) => {
switch (kind) {
case 'CronJob':
return delCronJobByName(instanceName);
case 'App':
return deleteAppCRD(instanceName);
case 'Secret':
return deleteSecret(instanceName);
case 'AppLaunchpad':
return delApplaunchpad(instanceName);
case 'DataBase':
return delDBByName(instanceName);
case 'Instance':
return delInstanceByName(instanceName);
case 'Job':
return delJobByName(instanceName);
default:
throw new Error(`Unsupported kind: ${kind}`);
}
export const delConfigMapByName = (instanceName: string) =>
DELETE('/api/resource/delConfigMap', { instanceName });

export const delIssuerByName = (instanceName: string) =>
DELETE('/api/resource/deleteIssuer', { instanceName });

export const delRoleByName = (instanceName: string) =>
DELETE('/api/resource/delRole', { instanceName });

export const delRoleBindingByName = (instanceName: string) =>
DELETE('/api/resource/delRoleBinding', { instanceName });

export const delServiceAccountByName = (instanceName: string) =>
DELETE('/api/resource/delServiceAccount', { instanceName });

const deleteResourceByKind: Record<ResourceKindType, (instanceName: string) => void> = {
CronJob: (instanceName: string) => delCronJobByName(instanceName),
App: (instanceName: string) => deleteAppCRD(instanceName),
Secret: (instanceName: string) => deleteSecret(instanceName),
AppLaunchpad: (instanceName: string) => delApplaunchpad(instanceName),
DataBase: (instanceName: string) => delDBByName(instanceName),
Instance: (instanceName: string) => delInstanceByName(instanceName),
Job: (instanceName: string) => delJobByName(instanceName),
ConfigMap: (instanceName: string) => delConfigMapByName(instanceName),
Issuer: (instanceName: string) => delIssuerByName(instanceName),
Role: (instanceName: string) => delRoleByName(instanceName),
RoleBinding: (instanceName: string) => delRoleBindingByName(instanceName),
ServiceAccount: (instanceName: string) => delServiceAccountByName(instanceName)
};

export const deleteAllResources = async (resources: BaseResourceType[]) => {
const deletePromises = resources.map((resource) => {
return deleteResourceByKind(resource.name, resource.kind);
return deleteResourceByKind[resource.kind](resource.name);
});
const reuslt = await Promise.allSettled(deletePromises);
console.log(reuslt);
Expand Down
1 change: 1 addition & 0 deletions frontend/providers/template/src/constants/keys.ts
Expand Up @@ -12,5 +12,6 @@ export const gpuResourceKey = 'nvidia.com/gpu';
export const templateDeployKey = 'cloud.sealos.io/deploy-on-sealos';
// db
export const kubeblocksTypeKey = 'clusterdefinition.kubeblocks.io/name';
export const dbProviderKey = 'sealos-db-provider-cr';
// labels
export const componentLabel = 'app.kubernetes.io/component';
75 changes: 70 additions & 5 deletions frontend/providers/template/src/pages/api/app/listOtherByName.ts
@@ -1,16 +1,15 @@
import { templateDeployKey } from '@/constants/keys';
import { dbProviderKey, deployManagerKey, templateDeployKey } from '@/constants/keys';
import { authSession } from '@/services/backend/auth';
import { CRDMeta, getK8s } from '@/services/backend/kubernetes';
import { jsonRes } from '@/services/backend/response';
import { ApiResp } from '@/services/kubernet';
import { AppCrdType } from '@/types/appCRD';
import { IncomingMessage } from 'http';
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(req: NextApiRequest, res: NextApiResponse<ApiResp>) {
try {
const { instanceName } = req.query as { instanceName: string };
const { namespace, k8sCore, k8sCustomObjects, k8sBatch } = await getK8s({
const { namespace, k8sCore, k8sCustomObjects, k8sBatch, k8sAuth } = await getK8s({
kubeconfig: await authSession(req.headers)
});
const labelSelector = `${templateDeployKey}=${instanceName}`;
Expand All @@ -22,6 +21,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
plural: 'apps'
};

// secret
const secretPromise = k8sCore.listNamespacedSecret(
namespace,
undefined,
Expand All @@ -31,6 +31,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
labelSelector
);

// job
const jobPromise = k8sBatch.listNamespacedJob(
namespace,
undefined,
Expand All @@ -40,6 +41,26 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
labelSelector
);

// issuer
const certIssuerPromise = k8sCustomObjects.listNamespacedCustomObject(
'cert-manager.io',
'v1',
namespace,
'issuers',
undefined,
undefined,
undefined,
undefined,
labelSelector
) as Promise<{
response: IncomingMessage;
body: {
items: { kind?: string }[];
kind: 'IssuerList';
};
}>;

// app cr
const appCrdResourcePromise = k8sCustomObjects.listNamespacedCustomObject(
appCRD.group,
appCRD.version,
Expand All @@ -53,17 +74,61 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
) as Promise<{
response: IncomingMessage;
body: {
items: AppCrdType[];
items: { kind?: string }[];
kind: 'AppList';
};
}>;

// role
const rolePromise = k8sAuth.listNamespacedRole(
namespace,
undefined,
undefined,
undefined,
undefined,
`${labelSelector},!${dbProviderKey}`
);
const roleBindingPromise = k8sAuth.listNamespacedRoleBinding(
namespace,
undefined,
undefined,
undefined,
undefined,
`${labelSelector},!${dbProviderKey}`
);
const saPromise = k8sCore.listNamespacedServiceAccount(
namespace,
undefined,
undefined,
undefined,
undefined,
`${labelSelector},!${dbProviderKey}`
);
const configMapPromise = k8sCore.listNamespacedConfigMap(
namespace,
undefined,
undefined,
undefined,
undefined,
`${labelSelector},!${dbProviderKey},!${deployManagerKey}`
);
// 使用 Promise.allSettled 获取所有结果 [secretResult, jobResult, customResourceResult]
const result = await Promise.allSettled([secretPromise, jobPromise, appCrdResourcePromise]);
const result = await Promise.allSettled([
secretPromise,
jobPromise,
appCrdResourcePromise,
certIssuerPromise,
rolePromise,
roleBindingPromise,
saPromise,
configMapPromise
]);

const data = result
.map((res) => {
if (res.status === 'fulfilled') {
return res.value.body.items.map((item) => {
// console.log(item, '==');
return {
...item,
kind: item.kind ? item.kind : res.value?.body?.kind?.replace('List', '')
Expand Down
27 changes: 27 additions & 0 deletions frontend/providers/template/src/pages/api/resource/delConfigMap.ts
@@ -0,0 +1,27 @@
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';

export default async function handler(req: NextApiRequest, res: NextApiResponse<ApiResp>) {
try {
const { instanceName } = req.query as { instanceName: string };
if (!instanceName) {
throw new Error('deploy name is empty');
}

const { namespace, k8sCore } = await getK8s({
kubeconfig: await authSession(req.headers)
});

const result = await k8sCore.deleteNamespacedConfigMap(instanceName, namespace);

jsonRes(res, { data: result });
} catch (err: any) {
jsonRes(res, {
code: 500,
error: err
});
}
}
27 changes: 27 additions & 0 deletions frontend/providers/template/src/pages/api/resource/delRole.ts
@@ -0,0 +1,27 @@
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';

export default async function handler(req: NextApiRequest, res: NextApiResponse<ApiResp>) {
try {
const { instanceName } = req.query as { instanceName: string };
if (!instanceName) {
throw new Error('deploy name is empty');
}

const { namespace, k8sAuth } = await getK8s({
kubeconfig: await authSession(req.headers)
});

const result = await k8sAuth.deleteNamespacedRole(instanceName, namespace);

jsonRes(res, { data: result });
} catch (err: any) {
jsonRes(res, {
code: 500,
error: err
});
}
}
@@ -0,0 +1,27 @@
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';

export default async function handler(req: NextApiRequest, res: NextApiResponse<ApiResp>) {
try {
const { instanceName } = req.query as { instanceName: string };
if (!instanceName) {
throw new Error('deploy name is empty');
}

const { namespace, k8sAuth } = await getK8s({
kubeconfig: await authSession(req.headers)
});

const result = await k8sAuth.deleteClusterRoleBinding(instanceName, namespace);

jsonRes(res, { data: result });
} catch (err: any) {
jsonRes(res, {
code: 500,
error: err
});
}
}
@@ -0,0 +1,27 @@
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';

export default async function handler(req: NextApiRequest, res: NextApiResponse<ApiResp>) {
try {
const { instanceName } = req.query as { instanceName: string };
if (!instanceName) {
throw new Error('deploy name is empty');
}

const { namespace, k8sCore } = await getK8s({
kubeconfig: await authSession(req.headers)
});

const result = await k8sCore.deleteNamespacedServiceAccount(instanceName, namespace);

jsonRes(res, { data: result });
} catch (err: any) {
jsonRes(res, {
code: 500,
error: err
});
}
}
Expand Up @@ -6,27 +6,28 @@ import { jsonRes } from '@/services/backend/response';

export default async function handler(req: NextApiRequest, res: NextApiResponse<ApiResp>) {
try {
const { namespace } = req.query as { namespace: string };
const { k8sCustomObjects } = await getK8s({
const { instanceName } = req.query as { instanceName: string };
const { k8sCustomObjects, namespace } = await getK8s({
kubeconfig: await authSession(req.headers)
});

const customResource: CRDMeta = {
group: 'app.sealos.io',
group: 'cert-manager.io',
version: 'v1',
namespace: namespace,
plural: 'apps'
plural: 'issuers'
};

// 获取指定命名空间中的所有自定义资源
const customResourceList = await k8sCustomObjects.listNamespacedCustomObject(
// 删除指定名称的自定义资源
const reuslt = await k8sCustomObjects.deleteNamespacedCustomObject(
customResource.group,
customResource.version,
customResource.namespace,
customResource.plural
customResource.plural,
instanceName
);

jsonRes(res, { data: customResourceList, message: 'retrieved successfully' });
jsonRes(res, { data: reuslt });
} catch (err: any) {
jsonRes(res, {
code: 500,
Expand Down
5 changes: 5 additions & 0 deletions frontend/providers/template/src/types/resource.ts
Expand Up @@ -11,6 +11,11 @@ export type ResourceKindType =
| 'App'
| 'Job'
| 'Secret'
| 'Issuer'
| 'Role'
| 'RoleBinding'
| 'ServiceAccount'
| 'ConfigMap'
| 'Instance';

export type OtherResourceListItemType = {
Expand Down

0 comments on commit 733e877

Please sign in to comment.