From 7974ba511348f0e1a1acb472e694c460744a9cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=92=E6=83=85=E7=86=8A?= <2669184984@qq.com> Date: Tue, 14 May 2024 18:17:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=BAkubepanel=20network=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0service=20(#4705)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 为kubepanel network 添加service 前端页面部分 * kubepanel添加service 后端接口新增 kubepanel添加service 后端接口新增 * 修改 撤回配置文件 * 撤回配置 * 撤回 * 撤回 * Update go.work.sum * Update pnpm-lock.yaml * Update pnpm-lock.yaml --- .../src/components/common/sidebar/sidebar.tsx | 8 +- .../kubepanel/src/constants/kube-object.ts | 3 +- .../kubepanel/src/pages/kubepanel/index.tsx | 3 + .../network/service/service-detail.tsx | 87 +++++++++++++++++++ .../kube-object/network/service/service.tsx | 66 ++++++++++++++ .../kubepanel/src/services/backend/api.ts | 5 ++ .../kubepanel/src/store/k8s/service.store.ts | 8 ++ .../providers/kubepanel/src/store/kube.ts | 1 + .../providers/kubepanel/src/types/state.d.ts | 1 + 9 files changed, 179 insertions(+), 3 deletions(-) create mode 100644 frontend/providers/kubepanel/src/pages/kubepanel/kube-object/network/service/service-detail.tsx create mode 100644 frontend/providers/kubepanel/src/pages/kubepanel/kube-object/network/service/service.tsx create mode 100644 frontend/providers/kubepanel/src/store/k8s/service.store.ts diff --git a/frontend/providers/kubepanel/src/components/common/sidebar/sidebar.tsx b/frontend/providers/kubepanel/src/components/common/sidebar/sidebar.tsx index 64ec359c2ec..70355d3aee9 100644 --- a/frontend/providers/kubepanel/src/components/common/sidebar/sidebar.tsx +++ b/frontend/providers/kubepanel/src/components/common/sidebar/sidebar.tsx @@ -18,7 +18,8 @@ export enum SideNavItemKey { PersistentVolumeClaim = 'volume-claim', StatefulSet = 'stateful-set', Secret = 'secret', - Ingress = 'ingress' + Ingress = 'ingress', + Service = 'service' } function getItem( @@ -48,7 +49,10 @@ const items: MenuProps['items'] = [ getItem('Config Maps', SideNavItemKey.ConfigMap), getItem('Secrets', SideNavItemKey.Secret) ]), - getItem('Network', 'network', , [getItem('Ingress', SideNavItemKey.Ingress)]), + getItem('Network', 'network', , [ + getItem('Ingress', SideNavItemKey.Ingress), + getItem('Service', SideNavItemKey.Service) + ]), getItem('Storage', 'storage', , [ getItem('Persistent Volume Claims', SideNavItemKey.PersistentVolumeClaim) ]) diff --git a/frontend/providers/kubepanel/src/constants/kube-object.ts b/frontend/providers/kubepanel/src/constants/kube-object.ts index 1ac6a1ed46a..7b5251fab91 100644 --- a/frontend/providers/kubepanel/src/constants/kube-object.ts +++ b/frontend/providers/kubepanel/src/constants/kube-object.ts @@ -6,5 +6,6 @@ export enum KubeObjectKind { PersistentVolumeClaim = 'PersistentVolumeClaim', Secret = 'Secret', Ingress = 'Ingress', - Event = 'Event' + Event = 'Event', + Service = 'Service' } diff --git a/frontend/providers/kubepanel/src/pages/kubepanel/index.tsx b/frontend/providers/kubepanel/src/pages/kubepanel/index.tsx index 12636e3828f..4fada9931a5 100644 --- a/frontend/providers/kubepanel/src/pages/kubepanel/index.tsx +++ b/frontend/providers/kubepanel/src/pages/kubepanel/index.tsx @@ -12,6 +12,7 @@ import { CreateResourceModal } from '@/components/common/action/create-resource- import { PlusOutlined } from '@ant-design/icons'; import SecretOverviewPage from './kube-object/config/secret/secret'; import IngressOverviewPage from './kube-object/network/ingress/ingress'; +import ServiceOverviewPage from './kube-object/network/service/service'; const switchPage = (key: SideNavItemKey): React.ReactNode => { switch (key) { @@ -31,6 +32,8 @@ const switchPage = (key: SideNavItemKey): React.ReactNode => { return ; case SideNavItemKey.Ingress: return ; + case SideNavItemKey.Service: + return ; default: return ; } diff --git a/frontend/providers/kubepanel/src/pages/kubepanel/kube-object/network/service/service-detail.tsx b/frontend/providers/kubepanel/src/pages/kubepanel/kube-object/network/service/service-detail.tsx new file mode 100644 index 00000000000..bffe0a2c19a --- /dev/null +++ b/frontend/providers/kubepanel/src/pages/kubepanel/kube-object/network/service/service-detail.tsx @@ -0,0 +1,87 @@ +import { KubeObjectInfoList } from '@/components/kube/object/detail/kube-object-detail-info-list'; +import { + ComputedIngressRoute, + ILoadBalancerIngress, + Service, + computeRuleDeclarations +} from '@/k8slens/kube-object'; +import { DrawerPanel } from '@/components/common/drawer/drawer-panel'; +import { Drawer } from '@/components/common/drawer/drawer'; +import { DrawerItem } from '@/components/common/drawer/drawer-item'; +import { Button, Table } from 'antd'; +import { ColumnsType } from 'antd/lib/table'; + +const rulesColumns: ColumnsType = [ + { + key: 'path', + title: 'Path', + dataIndex: 'pathname', + render: (pathname: string) => (pathname === '' ? '_' : pathname) + }, + { + key: 'link', + title: 'Link', + render: (_, { displayAsLink, url }) => + displayAsLink ? ( + + ) : ( + url + ) + }, + { + key: 'backends', + title: 'Backends', + dataIndex: 'service' + } +]; + +const pointsColumns: ColumnsType = [ + { + key: 'hostname', + title: 'Hostname', + dataIndex: 'hostname', + render: (hostname?: string) => (hostname ? '_' : hostname) + }, + { + key: 'ip', + title: 'IP', + dataIndex: 'ip', + render: (ip?: string) => (ip ? '_' : ip) + } +]; + +const IngressPoints = ({ points }: { points?: ILoadBalancerIngress[] }) => { + if (!points || points.length === 0) { + return null; + } + + return ( + + ); +}; + +const ServiceDetail = ({ obj: service, open, onClose }: DetailDrawerProps) => { + if (!service || !(service instanceof Service)) return null; + return ( + + + + + + + port.toString()).join(", ")} /> + {/* Add other relevant details here */} + + +) +}; + +export default ServiceDetail; diff --git a/frontend/providers/kubepanel/src/pages/kubepanel/kube-object/network/service/service.tsx b/frontend/providers/kubepanel/src/pages/kubepanel/kube-object/network/service/service.tsx new file mode 100644 index 00000000000..fe9475bac60 --- /dev/null +++ b/frontend/providers/kubepanel/src/pages/kubepanel/kube-object/network/service/service.tsx @@ -0,0 +1,66 @@ +import { KubeObjectAge } from '@/components/kube/object/kube-object-age'; +import { KubeObject,KubeObjectMetadata,KubeObjectScope,Service, computeRouteDeclarations } from '@/k8slens/kube-object'; +import { ColumnsType } from 'antd/lib/table'; +import { useServiceStore } from '@/store/kube'; +import { Button } from 'antd'; +import ServiceDetail from './service-detail'; +import { PanelTable } from '@/components/common/panel-table/table'; +import { ActionButton } from '@/components/common/action/action-button'; + +const columns: ColumnsType = [ + { + title: 'ClusterIps', + key: 'ClusterIps', + render: (_, service: Service) => service.getClusterIps().map(ip =>

{ip}

) + }, + { + title: 'Type', + key: 'type', + render: (_, service: Service) => {service.getType()} + }, + { + title: 'Selector', + key: 'selector', + render: (_, service: Service) => service.getSelector().map(selector =>

{selector}

) + }, + { + title: 'Ports', + key: 'ports', + render: (_, service: Service) => + service.getPorts().map(port => ( +
+ {port.toString()} +
+ )) + }, + { + title: 'Load Balancer IPs', + key: 'load-balancer-ips', + render: (_, service: Service) => service.getExternalIps().map(ip =>

{ip}

) + }, + { + title: 'Status', + key: 'status', + render: (_, service: Service) => {service.getStatus()} + }, +]; + +const ServiceOverviewPage = () => { + const { items, initialize, isLoaded, watch } = useServiceStore(); + + return ( + service.getId()} + initializers={[initialize]} + watchers={[watch]} + getDetailItem={(service) => service} + /> + ); +}; + +export default ServiceOverviewPage; diff --git a/frontend/providers/kubepanel/src/services/backend/api.ts b/frontend/providers/kubepanel/src/services/backend/api.ts index 145b01c7eb6..9e191f58ab7 100644 --- a/frontend/providers/kubepanel/src/services/backend/api.ts +++ b/frontend/providers/kubepanel/src/services/backend/api.ts @@ -73,5 +73,10 @@ const ApiBaseParamsRecord: Record = { apiPrefix: 'api', apiVersion: 'v1', resource: 'events' + }, + [KubeObjectKind.Service]: { + apiPrefix: 'api', + apiVersion: 'v1', + resource: 'services' } }; diff --git a/frontend/providers/kubepanel/src/store/k8s/service.store.ts b/frontend/providers/kubepanel/src/store/k8s/service.store.ts new file mode 100644 index 00000000000..0f2df37780e --- /dev/null +++ b/frontend/providers/kubepanel/src/store/k8s/service.store.ts @@ -0,0 +1,8 @@ +import { ServiceStore} from '@/types/state'; +import { create } from 'zustand'; +import { createKubeStoreSlice } from './kube.store'; +import { Service } from '@/k8slens/kube-object'; + +export const useServiceStore = create()((...a) => ({ + ...createKubeStoreSlice(Service.kind, Service)(...a) +})); diff --git a/frontend/providers/kubepanel/src/store/kube.ts b/frontend/providers/kubepanel/src/store/kube.ts index 7a06c6ae19a..0165bfaa8c4 100644 --- a/frontend/providers/kubepanel/src/store/kube.ts +++ b/frontend/providers/kubepanel/src/store/kube.ts @@ -6,3 +6,4 @@ export * from './k8s/volume-claim.store'; export * from './k8s/ingress.store'; export * from './k8s/secret.store'; export * from './k8s/kube.store'; +export * from './k8s/service.store'; diff --git a/frontend/providers/kubepanel/src/types/state.d.ts b/frontend/providers/kubepanel/src/types/state.d.ts index 80c0f10bebe..5a670f476bb 100644 --- a/frontend/providers/kubepanel/src/types/state.d.ts +++ b/frontend/providers/kubepanel/src/types/state.d.ts @@ -45,3 +45,4 @@ type VolumeClaimStore = KubeStore; type SecretStore = KubeStore; type IngressStore = KubeStore; type EventStore = KubeStore; +type ServiceStore = KubeStore; \ No newline at end of file