mirror of
https://github.com/labring/sealos.git
synced 2026-09-24 15:46:19 +08:00
为kubepanel network 添加service (#4705)
* 为kubepanel network 添加service 前端页面部分 * kubepanel添加service 后端接口新增 kubepanel添加service 后端接口新增 * 修改 撤回配置文件 * 撤回配置 * 撤回 * 撤回 * Update go.work.sum * Update pnpm-lock.yaml * Update pnpm-lock.yaml
This commit is contained in:
@@ -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', <GatewayOutlined />, [getItem('Ingress', SideNavItemKey.Ingress)]),
|
||||
getItem('Network', 'network', <GatewayOutlined />, [
|
||||
getItem('Ingress', SideNavItemKey.Ingress),
|
||||
getItem('Service', SideNavItemKey.Service)
|
||||
]),
|
||||
getItem('Storage', 'storage', <DatabaseOutlined />, [
|
||||
getItem('Persistent Volume Claims', SideNavItemKey.PersistentVolumeClaim)
|
||||
])
|
||||
|
||||
@@ -6,5 +6,6 @@ export enum KubeObjectKind {
|
||||
PersistentVolumeClaim = 'PersistentVolumeClaim',
|
||||
Secret = 'Secret',
|
||||
Ingress = 'Ingress',
|
||||
Event = 'Event'
|
||||
Event = 'Event',
|
||||
Service = 'Service'
|
||||
}
|
||||
|
||||
@@ -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 <SecretOverviewPage />;
|
||||
case SideNavItemKey.Ingress:
|
||||
return <IngressOverviewPage />;
|
||||
case SideNavItemKey.Service:
|
||||
return <ServiceOverviewPage />;
|
||||
default:
|
||||
return <OverviewPage />;
|
||||
}
|
||||
|
||||
+87
@@ -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<ComputedIngressRoute> = [
|
||||
{
|
||||
key: 'path',
|
||||
title: 'Path',
|
||||
dataIndex: 'pathname',
|
||||
render: (pathname: string) => (pathname === '' ? '_' : pathname)
|
||||
},
|
||||
{
|
||||
key: 'link',
|
||||
title: 'Link',
|
||||
render: (_, { displayAsLink, url }) =>
|
||||
displayAsLink ? (
|
||||
<Button
|
||||
href={url}
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
type="link"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{url}
|
||||
</Button>
|
||||
) : (
|
||||
url
|
||||
)
|
||||
},
|
||||
{
|
||||
key: 'backends',
|
||||
title: 'Backends',
|
||||
dataIndex: 'service'
|
||||
}
|
||||
];
|
||||
|
||||
const pointsColumns: ColumnsType<ILoadBalancerIngress> = [
|
||||
{
|
||||
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 (
|
||||
<Table size="small" bordered columns={pointsColumns} dataSource={points} pagination={false} />
|
||||
);
|
||||
};
|
||||
|
||||
const ServiceDetail = ({ obj: service, open, onClose }: DetailDrawerProps<Service>) => {
|
||||
if (!service || !(service instanceof Service)) return null;
|
||||
return (
|
||||
<Drawer open={open} title={`Service: ${service.getName()}`} onClose={onClose}>
|
||||
<DrawerPanel>
|
||||
<KubeObjectInfoList obj={service} />
|
||||
<DrawerItem name="Cluster IP" value={service.getClusterIp()} />
|
||||
<DrawerItem name="External IPs" value={service.getExternalIps().join(", ")} />
|
||||
<DrawerItem name="Type" value={service.getType()} />
|
||||
<DrawerItem name="Ports" value={service.getPorts().map(port => port.toString()).join(", ")} />
|
||||
{/* Add other relevant details here */}
|
||||
</DrawerPanel>
|
||||
</Drawer>
|
||||
)
|
||||
};
|
||||
|
||||
export default ServiceDetail;
|
||||
+66
@@ -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<Service> = [
|
||||
{
|
||||
title: 'ClusterIps',
|
||||
key: 'ClusterIps',
|
||||
render: (_, service: Service) => service.getClusterIps().map(ip => <p key={ip}>{ip}</p>)
|
||||
},
|
||||
{
|
||||
title: 'Type',
|
||||
key: 'type',
|
||||
render: (_, service: Service) => <span>{service.getType()}</span>
|
||||
},
|
||||
{
|
||||
title: 'Selector',
|
||||
key: 'selector',
|
||||
render: (_, service: Service) => service.getSelector().map(selector => <p key={selector}>{selector}</p>)
|
||||
},
|
||||
{
|
||||
title: 'Ports',
|
||||
key: 'ports',
|
||||
render: (_, service: Service) =>
|
||||
service.getPorts().map(port => (
|
||||
<div key={port.toString()} className="overflow-hidden">
|
||||
{port.toString()}
|
||||
</div>
|
||||
))
|
||||
},
|
||||
{
|
||||
title: 'Load Balancer IPs',
|
||||
key: 'load-balancer-ips',
|
||||
render: (_, service: Service) => service.getExternalIps().map(ip => <p key={ip}>{ip}</p>)
|
||||
},
|
||||
{
|
||||
title: 'Status',
|
||||
key: 'status',
|
||||
render: (_, service: Service) => <span>{service.getStatus()}</span>
|
||||
},
|
||||
];
|
||||
|
||||
const ServiceOverviewPage = () => {
|
||||
const { items, initialize, isLoaded, watch } = useServiceStore();
|
||||
|
||||
return (
|
||||
<PanelTable
|
||||
columns={columns}
|
||||
dataSource={items}
|
||||
loading={!isLoaded}
|
||||
sectionTitle="service"
|
||||
DetailDrawer={ServiceDetail}
|
||||
getRowKey={(service) => service.getId()}
|
||||
initializers={[initialize]}
|
||||
watchers={[watch]}
|
||||
getDetailItem={(service) => service}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ServiceOverviewPage;
|
||||
@@ -73,5 +73,10 @@ const ApiBaseParamsRecord: Record<KubeObjectKind, KubeApiUrlParams> = {
|
||||
apiPrefix: 'api',
|
||||
apiVersion: 'v1',
|
||||
resource: 'events'
|
||||
},
|
||||
[KubeObjectKind.Service]: {
|
||||
apiPrefix: 'api',
|
||||
apiVersion: 'v1',
|
||||
resource: 'services'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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<ServiceStore>()((...a) => ({
|
||||
...createKubeStoreSlice<Service>(Service.kind, Service)(...a)
|
||||
}));
|
||||
@@ -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';
|
||||
|
||||
@@ -45,3 +45,4 @@ type VolumeClaimStore = KubeStore<PersistentVolumeClaim>;
|
||||
type SecretStore = KubeStore<Secret>;
|
||||
type IngressStore = KubeStore<Ingress>;
|
||||
type EventStore = KubeStore<KubeEvent>;
|
||||
type ServiceStore = KubeStore<Service>;
|
||||
Reference in New Issue
Block a user