refactor: 全局重命名 k8s → kubernetes (前后端+路由+表名+文件)
后端: - pkg/k8sclient → pkg/kubernetesclient - models/k8s.go → models/kubernetes.go - handlers/k8s.go → handlers/kubernetes.go - K8sCluster/K8sNode/.. → KubernetesCluster/KubernetesNode/.. - K8sHandler → KubernetesHandler - 路由: /k8s-clusters → /kubernetes-clusters - 路由: /k8s/:code/namespace/:ns/... → /kubernetes/:code/namespace/:ns/... (Kuboard风格) - 表前缀: container_k8s_ → container_kubernetes_ 前端: - components/k8s/ → components/kubernetes/ - K8sClusters → KubernetesClusters - K8sWorkloads → KubernetesWorkloads - K8sNodes → KubernetesNodes - k8sApi → kubernetesApi - 路由前缀: /k8s/ → /kubernetes/ 测试验证: ✅ /kubernetes/k8s-cluster-liren/namespace/kube-system/deployments → 3 items ✅ /kubernetes/k8s-cluster-liren/namespace/kube-system/pods → 7 items ✅ /kubernetes/k8s-cluster-liren/namespace/kube-system/services → 4 items ✅ /kubernetes/k8s-cluster-liren/namespace/kube-system/configmaps → 6 items ✅ /kubernetes/k8s-cluster-liren/namespace/kube-system/secrets → 1 item ✅ /kubernetes/k8s-cluster-liren/namespaces → 4 items
This commit is contained in:
1 parent
f7b667b878
commit
cac1414917
27 files changed
+779
-284
No files matched your search
@@ -12,10 +12,10 @@ import { DomainManager } from '@/components/cloud/DomainManager';
|
||||
import { RegionManager } from '@/components/cloud/RegionManager';
|
||||
import { PlatformManager } from '@/components/cloud/PlatformManager';
|
||||
import { CloudBilling } from '@/components/cloud/CloudBilling';
|
||||
import { K8sClusters } from '@/components/k8s/K8sClusters';
|
||||
import { K8sNodes } from '@/components/k8s/K8sNodes';
|
||||
import { K8sWorkloads } from '@/components/k8s/K8sWorkloads';
|
||||
import { TopologyView } from '@/components/k8s/TopologyView';
|
||||
import { KubernetesClusters } from '@/components/kubernetes/KubernetesClusters';
|
||||
import { KubernetesNodes } from '@/components/kubernetes/KubernetesNodes';
|
||||
import { KubernetesWorkloads } from '@/components/kubernetes/KubernetesWorkloads';
|
||||
import { TopologyView } from '@/components/kubernetes/TopologyView';
|
||||
import { AlertManager } from '@/components/monitor/AlertManager';
|
||||
import { AppReleaseManager } from '@/components/deploy/AppRelease';
|
||||
import { ApprovalFlowManager } from '@/components/approval/ApprovalFlow';
|
||||
@@ -65,9 +65,9 @@ function App() {
|
||||
<Route path="cloud-billing" element={<CloudBilling />} />
|
||||
{/* 资源监控(Agent 指标 + 中间件 + SNMP + 拨测) */}
|
||||
<Route path="monitor-center" element={<MonitorCenter />} />
|
||||
<Route path="clusters" element={<K8sClusters />} />
|
||||
<Route path="nodes" element={<K8sNodes />} />
|
||||
<Route path="workloads" element={<K8sWorkloads />} />
|
||||
<Route path="clusters" element={<KubernetesClusters />} />
|
||||
<Route path="nodes" element={<KubernetesNodes />} />
|
||||
<Route path="workloads" element={<KubernetesWorkloads />} />
|
||||
<Route path="topology" element={<TopologyView />} />
|
||||
{/* 应用发布 */}
|
||||
<Route path="pipelines" element={<PipelineManager />} />
|
||||
|
||||
@@ -102,7 +102,7 @@ async function loadReportContext(): Promise<string> {
|
||||
dashboardStatsApi.getReleases(10).catch(() => null),
|
||||
]);
|
||||
const s: any = stats || {};
|
||||
const ss = s.server_stats || {}, ks = s.k8s_stats || {}, as = s.alert_stats || {}, ps = s.pipeline_stats || {}, cs = s.cost_stats || {};
|
||||
const ss = s.server_stats || {}, ks = s.kubernetes_stats || {}, as = s.alert_stats || {}, ps = s.pipeline_stats || {}, cs = s.cost_stats || {};
|
||||
const overview = `服务器:${ss.total ?? 0}(运行${ss.running ?? 0}) | K8s集群:${ks.total ?? 0} 节点:${ks.total_nodes ?? 0} Pod:${ks.total_pods ?? 0} | 告警:${as.total ?? 0}(firing ${as.firing ?? 0}) | 流水线:${ps.total ?? 0}(成功率${ps.success_rate ?? 0}%) | 本月成本:¥${cs.month_cost ?? 0}`;
|
||||
const alertList: any[] = Array.isArray(alerts) ? alerts : (alerts as any)?.list || [];
|
||||
const releaseList: any[] = Array.isArray(releases) ? releases : (releases as any)?.list || [];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Clock, Server, Cloud, Bell, DollarSign } from 'lucide-react';
|
||||
import { dashboardStatsApi, serverApi, k8sApi } from '@/services/api';
|
||||
import { dashboardStatsApi, serverApi, kubernetesApi } from '@/services/api';
|
||||
import { StatCard } from './DashboardStats';
|
||||
import { CostOverviewCard, TopResourceUsageCard, ResourceUsageCard, computeMonthChange } from './DashboardCharts';
|
||||
import {
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
CertificateExpiryCard,
|
||||
ReleaseHistoryCard,
|
||||
ServerStatusCard,
|
||||
K8sClusterCard,
|
||||
KubernetesClusterCard,
|
||||
} from './DashboardRecent';
|
||||
|
||||
export function Dashboard() {
|
||||
@@ -35,7 +35,7 @@ export function Dashboard() {
|
||||
console.error('Failed to fetch servers:', e);
|
||||
return null;
|
||||
}),
|
||||
k8sApi.getClusters().catch((e) => {
|
||||
kubernetesApi.getClusters().catch((e) => {
|
||||
console.error('Failed to fetch k8s clusters:', e);
|
||||
return null;
|
||||
}),
|
||||
@@ -82,7 +82,7 @@ export function Dashboard() {
|
||||
}
|
||||
|
||||
const serverStats = stats?.server_stats;
|
||||
const k8sStats = stats?.k8s_stats;
|
||||
const k8sStats = stats?.kubernetes_stats;
|
||||
const alertStats = stats?.alert_stats;
|
||||
const costStats = stats?.cost_stats;
|
||||
const costChange = computeMonthChange(costStats?.month_trend);
|
||||
@@ -165,7 +165,7 @@ export function Dashboard() {
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
<ReleaseHistoryCard releases={releases} />
|
||||
<ServerStatusCard servers={servers} />
|
||||
<K8sClusterCard clusters={clusters} />
|
||||
<KubernetesClusterCard clusters={clusters} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -295,7 +295,7 @@ export function ServerStatusCard({ servers }: { servers: any[] }) {
|
||||
}
|
||||
|
||||
// K8s集群状态卡片
|
||||
export function K8sClusterCard({ clusters }: { clusters: any[] }) {
|
||||
export function KubernetesClusterCard({ clusters }: { clusters: any[] }) {
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<Card className="bg-slate-900 border-slate-800">
|
||||
|
||||
+18
-18
@@ -14,17 +14,17 @@ import {
|
||||
Gauge, Clock, Play, Pause, Trash2, RefreshCw, Loader2,
|
||||
CheckCircle, AlertTriangle, XCircle, ExternalLink,
|
||||
} from 'lucide-react';
|
||||
import { k8sApi } from '@/services/api';
|
||||
import { kubernetesApi } from '@/services/api';
|
||||
import { useToast } from '@/hooks/use-toast';
|
||||
|
||||
interface DeploymentDetailProps {
|
||||
clusterId: string;
|
||||
clusterCode: string;
|
||||
namespace: string;
|
||||
deploymentName: string;
|
||||
onBack: () => void;
|
||||
}
|
||||
|
||||
export function DeploymentDetail({ clusterId, namespace, deploymentName, onBack }: DeploymentDetailProps) {
|
||||
export function DeploymentDetail({ clusterCode, namespace, deploymentName, onBack }: DeploymentDetailProps) {
|
||||
const { toast } = useToast();
|
||||
const [deployment, setDeployment] = useState<any>(null);
|
||||
const [pods, setPods] = useState<any[]>([]);
|
||||
@@ -47,9 +47,9 @@ export function DeploymentDetail({ clusterId, namespace, deploymentName, onBack
|
||||
setLoading(true);
|
||||
try {
|
||||
const [depRes, podRes, hpaRes] = await Promise.all([
|
||||
k8sApi.getDeployments(clusterId).catch(() => []),
|
||||
k8sApi.getPods(clusterId).catch(() => []),
|
||||
k8sApi.getHPAs(clusterId).catch(() => ({ items: [] })),
|
||||
kubernetesApi.getNamespaceDeployments(clusterCode, namespace).catch(() => []),
|
||||
kubernetesApi.getNamespacePods(clusterCode, namespace).catch(() => []),
|
||||
kubernetesApi.getHPAs(clusterCode, namespace).catch(() => ({ items: [] })),
|
||||
]);
|
||||
const toArray = (v: any) => (Array.isArray(v) ? v : (v?.list || v?.items || []));
|
||||
const allDeps = toArray(depRes);
|
||||
@@ -80,7 +80,7 @@ export function DeploymentDetail({ clusterId, namespace, deploymentName, onBack
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [clusterId, namespace, deploymentName]);
|
||||
}, [clusterCode, namespace, deploymentName]);
|
||||
|
||||
useEffect(() => { loadData(); }, [loadData]);
|
||||
|
||||
@@ -89,7 +89,7 @@ export function DeploymentDetail({ clusterId, namespace, deploymentName, onBack
|
||||
if (newReplicas < 0) return;
|
||||
setActionLoading('scale');
|
||||
try {
|
||||
await k8sApi.scaleDeployment(clusterId, namespace, deploymentName, newReplicas);
|
||||
await kubernetesApi.scaleDeployment(clusterCode, namespace, deploymentName, newReplicas);
|
||||
toast({ title: '扩缩容成功', description: `副本数已设置为 ${newReplicas}` });
|
||||
loadData();
|
||||
} catch (e: any) {
|
||||
@@ -100,7 +100,7 @@ export function DeploymentDetail({ clusterId, namespace, deploymentName, onBack
|
||||
const handleRestart = async () => {
|
||||
setActionLoading('restart');
|
||||
try {
|
||||
await k8sApi.restartDeployment(clusterId, namespace, deploymentName);
|
||||
await kubernetesApi.restartDeployment(clusterCode, namespace, deploymentName);
|
||||
toast({ title: '重启指令已下发', description: 'Deployment 正在滚动重启' });
|
||||
} catch (e: any) {
|
||||
toast({ title: '重启失败', description: e?.message || String(e), variant: 'destructive' });
|
||||
@@ -111,7 +111,7 @@ export function DeploymentDetail({ clusterId, namespace, deploymentName, onBack
|
||||
if (!newImage.trim()) return;
|
||||
setActionLoading('image');
|
||||
try {
|
||||
await k8sApi.updateDeploymentImage(clusterId, namespace, deploymentName, newImage);
|
||||
await kubernetesApi.updateDeploymentImage(clusterCode, namespace, deploymentName, newImage);
|
||||
toast({ title: '镜像更新成功', description: `正在滚动更新为 ${newImage}` });
|
||||
setShowImageUpdate(false);
|
||||
loadData();
|
||||
@@ -125,7 +125,7 @@ export function DeploymentDetail({ clusterId, namespace, deploymentName, onBack
|
||||
setShowLogs(true);
|
||||
setLogs('');
|
||||
try {
|
||||
const res: any = await k8sApi.getPodLogs(clusterId, namespace, podName, logTail);
|
||||
const res: any = await kubernetesApi.getPodLogs(clusterCode, namespace, podName, logTail);
|
||||
setLogs(res?.data?.logs || res?.logs || '无日志');
|
||||
} catch {
|
||||
setLogs('获取日志失败');
|
||||
@@ -136,7 +136,7 @@ export function DeploymentDetail({ clusterId, namespace, deploymentName, onBack
|
||||
// Not direct toggle — delete HPA
|
||||
if (!confirm(`确定删除 HPA "${hpa.metadata?.name}"?`)) return;
|
||||
try {
|
||||
await k8sApi.deleteHPA(clusterId, namespace, hpa.metadata?.name);
|
||||
await kubernetesApi.deleteHPA(clusterCode, namespace, hpa.metadata?.name);
|
||||
toast({ title: 'HPA 已删除' });
|
||||
loadData();
|
||||
} catch (e: any) {
|
||||
@@ -226,7 +226,7 @@ export function DeploymentDetail({ clusterId, namespace, deploymentName, onBack
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="text-lg font-bold text-slate-500">未配置</p>
|
||||
<CreateHPADialog
|
||||
clusterId={clusterId}
|
||||
clusterCode={clusterCode}
|
||||
namespace={namespace}
|
||||
deploymentName={deploymentName}
|
||||
onCreated={loadData}
|
||||
@@ -407,7 +407,7 @@ export function DeploymentDetail({ clusterId, namespace, deploymentName, onBack
|
||||
setLogs('');
|
||||
// Stream mode
|
||||
const token = localStorage.getItem('token') || '';
|
||||
const url = `${window.location.protocol}//${window.location.host}/api/v1/k8s-clusters/${clusterId}/namespaces/${namespace}/pods/${logPod}/logs?tail=${logTail}&stream=true`;
|
||||
const url = `${window.location.protocol}//${window.location.host}/api/v1/kubernetes/${clusterCode}/namespace/${namespace}/pods/${logPod}/logs?tail=${logTail}&stream=true`;
|
||||
try {
|
||||
const resp = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
|
||||
const reader = resp.body?.getReader();
|
||||
@@ -444,7 +444,7 @@ export function DeploymentDetail({ clusterId, namespace, deploymentName, onBack
|
||||
<div className="flex items-center justify-between">
|
||||
<CardTitle className="text-sm text-slate-400">HPA 自动扩缩容</CardTitle>
|
||||
<CreateHPADialog
|
||||
clusterId={clusterId}
|
||||
clusterCode={clusterCode}
|
||||
namespace={namespace}
|
||||
deploymentName={deploymentName}
|
||||
onCreated={loadData}
|
||||
@@ -506,8 +506,8 @@ export function DeploymentDetail({ clusterId, namespace, deploymentName, onBack
|
||||
// ============================================================================
|
||||
// Create HPA Dialog (inline)
|
||||
// ============================================================================
|
||||
function CreateHPADialog({ clusterId, namespace, deploymentName, onCreated }: {
|
||||
clusterId: string; namespace: string; deploymentName: string; onCreated: () => void;
|
||||
function CreateHPADialog({ clusterCode, namespace, deploymentName, onCreated }: {
|
||||
clusterCode: string; namespace: string; deploymentName: string; onCreated: () => void;
|
||||
}) {
|
||||
const { toast } = useToast();
|
||||
const [open, setOpen] = useState(false);
|
||||
@@ -527,7 +527,7 @@ function CreateHPADialog({ clusterId, namespace, deploymentName, onCreated }: {
|
||||
}
|
||||
setLoading(true);
|
||||
try {
|
||||
await k8sApi.createHPA(clusterId, {
|
||||
await kubernetesApi.createHPA(clusterCode, {
|
||||
name: form.name,
|
||||
namespace,
|
||||
targetKind: 'Deployment',
|
||||
+7
-7
@@ -4,7 +4,7 @@ import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||
import { Cloud, XCircle } from 'lucide-react';
|
||||
import { k8sApi } from '@/services/api';
|
||||
import { kubernetesApi } from '@/services/api';
|
||||
import {
|
||||
AreaChart,
|
||||
Area,
|
||||
@@ -26,7 +26,7 @@ const resourceData = [
|
||||
{ time: '24:00', cpu: 48, memory: 56 },
|
||||
];
|
||||
|
||||
export function K8sClusterDetail({ cluster, onClose }: { cluster: any; onClose: () => void }) {
|
||||
export function KubernetesClusterDetail({ cluster, onClose }: { cluster: any; onClose: () => void }) {
|
||||
const [nodes, setNodes] = useState<any[]>([]);
|
||||
const [pods, setPods] = useState<any[]>([]);
|
||||
const [deployments, setDeployments] = useState<any[]>([]);
|
||||
@@ -37,11 +37,11 @@ export function K8sClusterDetail({ cluster, onClose }: { cluster: any; onClose:
|
||||
try {
|
||||
// 后端 ListNodes/ListPods/etc 返回 data 直接为数组(非 {list,total})
|
||||
const [nodesRes, podsRes, depRes, svcRes, ingRes] = await Promise.all([
|
||||
k8sApi.getNodes(clusterId).catch(() => []),
|
||||
k8sApi.getPods(clusterId).catch(() => []),
|
||||
k8sApi.getDeployments(clusterId).catch(() => []),
|
||||
k8sApi.getServices(clusterId).catch(() => []),
|
||||
k8sApi.getIngresses(clusterId).catch(() => []),
|
||||
kubernetesApi.getNodes(clusterId).catch(() => []),
|
||||
kubernetesApi.getPods(clusterId).catch(() => []),
|
||||
kubernetesApi.getDeployments(clusterId).catch(() => []),
|
||||
kubernetesApi.getServices(clusterId).catch(() => []),
|
||||
kubernetesApi.getIngresses(clusterId).catch(() => []),
|
||||
]);
|
||||
const toArray = (v: any) => (Array.isArray(v) ? v : (v?.list || []));
|
||||
setNodes(toArray(nodesRes));
|
||||
+5
-5
@@ -12,7 +12,7 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@/components/ui/dialog';
|
||||
import { k8sApi } from '@/services/api';
|
||||
import { kubernetesApi } from '@/services/api';
|
||||
|
||||
const emptyForm = {
|
||||
name: '',
|
||||
@@ -24,7 +24,7 @@ const emptyForm = {
|
||||
kube_config: '',
|
||||
};
|
||||
|
||||
export function K8sClusterDialog({
|
||||
export function KubernetesClusterDialog({
|
||||
open,
|
||||
onOpenChange,
|
||||
editingCluster,
|
||||
@@ -45,7 +45,7 @@ export function K8sClusterDialog({
|
||||
if (!open) return;
|
||||
if (editingCluster && editingCluster.id) {
|
||||
// 编辑模式:拉取详情获取 has_token/has_kube_config 标记 // Logan.Li
|
||||
k8sApi.getClusterDetail(editingCluster.id).then((res: any) => {
|
||||
kubernetesApi.getClusterDetail(editingCluster.id).then((res: any) => {
|
||||
const d = res || {};
|
||||
setHasToken(!!d.has_token);
|
||||
setHasKubeConfig(!!d.has_kube_config);
|
||||
@@ -106,9 +106,9 @@ export function K8sClusterDialog({
|
||||
kube_config: formData.config_type === 1 ? formData.kube_config : '',
|
||||
};
|
||||
if (editingCluster) {
|
||||
await k8sApi.updateCluster(editingCluster.id, payload);
|
||||
await kubernetesApi.updateCluster(editingCluster.id, payload);
|
||||
} else {
|
||||
await k8sApi.createCluster(payload);
|
||||
await kubernetesApi.createCluster(payload);
|
||||
}
|
||||
onOpenChange(false);
|
||||
onSaved();
|
||||
+10
-10
@@ -27,12 +27,12 @@ import {
|
||||
Trash2,
|
||||
Search,
|
||||
} from 'lucide-react';
|
||||
import { k8sApi } from '@/services/api';
|
||||
import type { K8sCluster } from '@/types';
|
||||
import { K8sClusterDetail } from './K8sClusterDetail';
|
||||
import { K8sClusterDialog } from './K8sClusterDialog';
|
||||
import { kubernetesApi } from '@/services/api';
|
||||
import type { KubernetesCluster } from '@/types';
|
||||
import { KubernetesClusterDetail } from './KubernetesClusterDetail';
|
||||
import { KubernetesClusterDialog } from './KubernetesClusterDialog';
|
||||
|
||||
export function K8sClusters() {
|
||||
export function KubernetesClusters() {
|
||||
const [clusters, setClusters] = useState<any[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [selectedCluster, setSelectedCluster] = useState<string | null>(null);
|
||||
@@ -45,7 +45,7 @@ export function K8sClusters() {
|
||||
const loadData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const res: any = await k8sApi.getClusters();
|
||||
const res: any = await kubernetesApi.getClusters();
|
||||
setClusters(res?.list || []);
|
||||
} catch (e) {
|
||||
console.error('加载集群列表失败:', e);
|
||||
@@ -61,7 +61,7 @@ export function K8sClusters() {
|
||||
|
||||
const handleDelete = async (id: string) => {
|
||||
try {
|
||||
await k8sApi.deleteCluster(id);
|
||||
await kubernetesApi.deleteCluster(id);
|
||||
loadData();
|
||||
} catch (e) {
|
||||
console.error('删除集群失败:', e);
|
||||
@@ -74,7 +74,7 @@ export function K8sClusters() {
|
||||
(cluster.version || '').includes(searchQuery)
|
||||
);
|
||||
|
||||
const getStatusBadge = (status: K8sCluster['status']) => {
|
||||
const getStatusBadge = (status: KubernetesCluster['status']) => {
|
||||
switch (status) {
|
||||
case 'healthy':
|
||||
return (
|
||||
@@ -345,11 +345,11 @@ export function K8sClusters() {
|
||||
|
||||
{/* Cluster Detail */}
|
||||
{clusterDetail && (
|
||||
<K8sClusterDetail cluster={clusterDetail} onClose={() => setSelectedCluster(null)} />
|
||||
<KubernetesClusterDetail cluster={clusterDetail} onClose={() => setSelectedCluster(null)} />
|
||||
)}
|
||||
|
||||
{/* 创建/编辑集群 Dialog */}
|
||||
<K8sClusterDialog
|
||||
<KubernetesClusterDialog
|
||||
open={dialogOpen}
|
||||
onOpenChange={setDialogOpen}
|
||||
editingCluster={editingCluster}
|
||||
+4
-4
@@ -10,9 +10,9 @@ import {
|
||||
Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
|
||||
} from '@/components/ui/table';
|
||||
import { RefreshCw, Search, Server, Loader2 } from 'lucide-react';
|
||||
import { k8sApi } from '@/services/api';
|
||||
import { kubernetesApi } from '@/services/api';
|
||||
|
||||
export function K8sNodes() {
|
||||
export function KubernetesNodes() {
|
||||
const [clusters, setClusters] = useState<any[]>([]);
|
||||
const [selectedCluster, setSelectedCluster] = useState('');
|
||||
const [nodes, setNodes] = useState<any[]>([]);
|
||||
@@ -22,7 +22,7 @@ export function K8sNodes() {
|
||||
|
||||
const loadClusters = useCallback(async () => {
|
||||
try {
|
||||
const res: any = await k8sApi.getClusters();
|
||||
const res: any = await kubernetesApi.getClusters();
|
||||
const list = res?.list || [];
|
||||
setClusters(list);
|
||||
if (list.length > 0 && !selectedCluster) setSelectedCluster(String(list[0].id));
|
||||
@@ -35,7 +35,7 @@ export function K8sNodes() {
|
||||
if (!selectedCluster) return;
|
||||
setLoading(true);
|
||||
try {
|
||||
const res: any = await k8sApi.getNodes(selectedCluster);
|
||||
const res: any = await kubernetesApi.getNodes(selectedCluster);
|
||||
setNodes(Array.isArray(res) ? res : (res?.list || []));
|
||||
} catch { setNodes([]); } finally { setLoading(false); }
|
||||
}, [selectedCluster]);
|
||||
+27
-16
@@ -14,11 +14,11 @@ import {
|
||||
RefreshCw, Search, Boxes, Loader2, Container,
|
||||
Plus, Minus, RotateCw, Upload, FileText, Eye,
|
||||
} from 'lucide-react';
|
||||
import { k8sApi } from '@/services/api';
|
||||
import { kubernetesApi } from '@/services/api';
|
||||
import { useToast } from '@/hooks/use-toast';
|
||||
import { DeploymentDetail } from './DeploymentDetail';
|
||||
|
||||
export function K8sWorkloads() {
|
||||
export function KubernetesWorkloads() {
|
||||
const { toast } = useToast();
|
||||
const [clusters, setClusters] = useState<any[]>([]);
|
||||
const [selectedCluster, setSelectedCluster] = useState('');
|
||||
@@ -36,10 +36,10 @@ export function K8sWorkloads() {
|
||||
|
||||
const loadClusters = useCallback(async () => {
|
||||
try {
|
||||
const res: any = await k8sApi.getClusters();
|
||||
const res: any = await kubernetesApi.getClusters();
|
||||
const list = res?.list || [];
|
||||
setClusters(list);
|
||||
if (list.length > 0 && !selectedCluster) setSelectedCluster(String(list[0].id));
|
||||
if (list.length > 0 && !selectedCluster) setSelectedCluster(list[0].code || String(list[0].id));
|
||||
} catch { setClusters([]); }
|
||||
}, []);
|
||||
|
||||
@@ -49,7 +49,7 @@ export function K8sWorkloads() {
|
||||
const loadNamespaces = useCallback(async () => {
|
||||
if (!selectedCluster) return;
|
||||
try {
|
||||
const res: any = await k8sApi.getNamespaces(selectedCluster);
|
||||
const res: any = await kubernetesApi.getNamespaces(selectedCluster);
|
||||
const nsList: string[] = Array.isArray(res) ? res : (res?.list || res?.data || []);
|
||||
setNamespaces(nsList);
|
||||
} catch { setNamespaces([]); }
|
||||
@@ -60,16 +60,27 @@ export function K8sWorkloads() {
|
||||
const loadData = useCallback(async () => {
|
||||
if (!selectedCluster) return;
|
||||
setLoading(true);
|
||||
const clusterCode = selectedCluster;
|
||||
try {
|
||||
const [depRes, podRes] = await Promise.all([
|
||||
k8sApi.getDeployments(selectedCluster).catch(() => []),
|
||||
k8sApi.getPods(selectedCluster).catch(() => []),
|
||||
]);
|
||||
const toArray = (v: any) => (Array.isArray(v) ? v : (v?.list || []));
|
||||
setDeployments(toArray(depRes));
|
||||
setPods(toArray(podRes));
|
||||
if (selectedNamespace !== 'all') {
|
||||
const [depRes, podRes] = await Promise.all([
|
||||
kubernetesApi.getNamespaceDeployments(clusterCode, selectedNamespace).catch(() => []),
|
||||
kubernetesApi.getNamespacePods(clusterCode, selectedNamespace).catch(() => []),
|
||||
]);
|
||||
const toArray = (v: any) => (Array.isArray(v) ? v : (v?.list || []));
|
||||
setDeployments(toArray(depRes));
|
||||
setPods(toArray(podRes));
|
||||
} else {
|
||||
const [depRes, podRes] = await Promise.all([
|
||||
kubernetesApi.getDeployments(clusterCode).catch(() => []),
|
||||
kubernetesApi.getPods(clusterCode).catch(() => []),
|
||||
]);
|
||||
const toArray = (v: any) => (Array.isArray(v) ? v : (v?.list || []));
|
||||
setDeployments(toArray(depRes));
|
||||
setPods(toArray(podRes));
|
||||
}
|
||||
} catch { setDeployments([]); setPods([]); } finally { setLoading(false); }
|
||||
}, [selectedCluster]);
|
||||
}, [selectedCluster, selectedNamespace]);
|
||||
|
||||
useEffect(() => { loadData(); }, [loadData]);
|
||||
|
||||
@@ -98,7 +109,7 @@ export function K8sWorkloads() {
|
||||
try {
|
||||
const newReplicas = (dep.replicas || 0) + delta;
|
||||
if (newReplicas < 0) return;
|
||||
await k8sApi.scaleDeployment(selectedCluster, dep.namespace, dep.name, newReplicas);
|
||||
await kubernetesApi.scaleDeployment(selectedCluster, dep.namespace, dep.name, newReplicas);
|
||||
toast({ title: '扩缩容成功', description: `${dep.name} → ${newReplicas} 副本` });
|
||||
loadData();
|
||||
} catch (e: any) {
|
||||
@@ -112,7 +123,7 @@ export function K8sWorkloads() {
|
||||
if (selectedDeployment) {
|
||||
return (
|
||||
<DeploymentDetail
|
||||
clusterId={selectedCluster}
|
||||
clusterCode={selectedCluster}
|
||||
namespace={selectedDeployment.namespace}
|
||||
deploymentName={selectedDeployment.name}
|
||||
onBack={() => { setSelectedDeployment(null); loadData(); }}
|
||||
@@ -134,7 +145,7 @@ export function K8sWorkloads() {
|
||||
</SelectTrigger>
|
||||
<SelectContent className="bg-slate-800 border-slate-700">
|
||||
{clusters.map((c) => (
|
||||
<SelectItem key={c.id} value={String(c.id)}>{c.name}</SelectItem>
|
||||
<SelectItem key={c.id} value={c.code || String(c.id)}>{c.name}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
+9
-9
@@ -14,7 +14,7 @@ import { Textarea } from '@/components/ui/textarea';
|
||||
import {
|
||||
Search, RefreshCw, Loader2, Cloud, Save, Plus, Trash2, Link2, Pencil, RotateCcw,
|
||||
} from 'lucide-react';
|
||||
import { k8sApi } from '@/services/api';
|
||||
import { kubernetesApi } from '@/services/api';
|
||||
import { useConfirm } from '@/components/ui/confirm-dialog';
|
||||
import { toast } from 'sonner';
|
||||
import type { TopologyNode, TopologyEdge } from '@/types';
|
||||
@@ -50,7 +50,7 @@ export function TopologyView() {
|
||||
|
||||
const loadClusters = useCallback(async () => {
|
||||
try {
|
||||
const res: any = await k8sApi.getClusters();
|
||||
const res: any = await kubernetesApi.getClusters();
|
||||
const list = res?.list || [];
|
||||
setClusters(list);
|
||||
if (list.length > 0 && !selectedClusterId) setSelectedClusterId(String(list[0].id));
|
||||
@@ -62,7 +62,7 @@ export function TopologyView() {
|
||||
// 加载已保存的布局 // Logan.Li
|
||||
const loadSavedLayout = useCallback(async (clusterId: string) => {
|
||||
try {
|
||||
const res: any = await k8sApi.getTopology(clusterId);
|
||||
const res: any = await kubernetesApi.getTopology(clusterId);
|
||||
const layout = res as any;
|
||||
if (layout?.layout_data) {
|
||||
const data = JSON.parse(layout.layout_data) as TopologyLayoutData;
|
||||
@@ -86,10 +86,10 @@ export function TopologyView() {
|
||||
try {
|
||||
const toArray = (v: any) => (Array.isArray(v) ? v : (v?.list || []));
|
||||
const [nodesRes, svcRes, depRes, ingRes] = await Promise.all([
|
||||
k8sApi.getNodes(selectedClusterId).catch(() => []),
|
||||
k8sApi.getServices(selectedClusterId).catch(() => []),
|
||||
k8sApi.getDeployments(selectedClusterId).catch(() => []),
|
||||
k8sApi.getIngresses(selectedClusterId).catch(() => []),
|
||||
kubernetesApi.getNodes(selectedClusterId).catch(() => []),
|
||||
kubernetesApi.getServices(selectedClusterId).catch(() => []),
|
||||
kubernetesApi.getDeployments(selectedClusterId).catch(() => []),
|
||||
kubernetesApi.getIngresses(selectedClusterId).catch(() => []),
|
||||
]);
|
||||
const cluster = clusters.find((c) => String(c.id) === selectedClusterId) || {};
|
||||
const built = buildTopology(cluster, toArray(ingRes), toArray(svcRes), toArray(depRes), toArray(nodesRes));
|
||||
@@ -246,7 +246,7 @@ export function TopologyView() {
|
||||
customNodes: topology.nodes.filter((n) => isCustomNode(n.id)),
|
||||
customEdges: topology.edges.filter((e) => e.id.startsWith('custom-edge')),
|
||||
};
|
||||
await k8sApi.saveTopology(selectedClusterId, JSON.stringify(layoutData));
|
||||
await kubernetesApi.saveTopology(selectedClusterId, JSON.stringify(layoutData));
|
||||
toast.success('布局已保存');
|
||||
} catch { toast.error('保存失败'); }
|
||||
finally { setSaving(false); }
|
||||
@@ -255,7 +255,7 @@ export function TopologyView() {
|
||||
const handleResetLayout = async () => {
|
||||
const ok = await _confirm({ title: '重置布局', description: '将清除已保存的布局并重新自动排列', variant: 'destructive' });
|
||||
if (!ok) return;
|
||||
try { await k8sApi.saveTopology(selectedClusterId, ''); } catch { /* */ }
|
||||
try { await kubernetesApi.saveTopology(selectedClusterId, ''); } catch { /* */ }
|
||||
setSavedLayout(null);
|
||||
setEditMode(false);
|
||||
setConnectMode(false);
|
||||
File renamed without changes.
@@ -62,7 +62,7 @@ const menuItems: MenuItem[] = [
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'k8s',
|
||||
id: 'kubernetes',
|
||||
name: 'Kubernetes',
|
||||
icon: Cloud,
|
||||
children: [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// 主机监控大屏 — Grafana 风格:统计卡片 + 资源条状图 + 可排序列表 // Logan.Li
|
||||
// 参照: Grafana node-dashboard.json (表格+时序) / k8s-dashboard.json (bargauge+阈值)
|
||||
// 参照: Grafana node-dashboard.json (表格+时序) / kubernetes-dashboard.json (bargauge+阈值)
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import {
|
||||
|
||||
@@ -122,7 +122,7 @@ export const PrometheusDashboard: React.FC<Props> = ({ dsUrl }) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [targets, setTargets] = useState(0);
|
||||
const [error, setError] = useState('');
|
||||
const [tab, setTab] = useState('k8s');
|
||||
const [tab, setTab] = useState('kubernetes');
|
||||
const [k8sD, setK8sD] = useState<any>({});
|
||||
const [nodeD, setNodeD] = useState<any>({});
|
||||
const [podD, setPodD] = useState<any>({});
|
||||
@@ -143,13 +143,13 @@ export const PrometheusDashboard: React.FC<Props> = ({ dsUrl }) => {
|
||||
};
|
||||
|
||||
const loadAll = async (u: string) => {
|
||||
for (const t of ['k8s','node','pod','jvm']) {
|
||||
for (const t of ['kubernetes','node','pod','jvm']) {
|
||||
try {
|
||||
const data: any = await http.post('/prometheus/dashboard', { url: u, type: t });
|
||||
const items: any = {};
|
||||
for (const [k, v] of Object.entries(data||{}))
|
||||
items[k] = Array.isArray(v) ? v : ((v as any)?.data?.result ? parsePrune((v as any).data.result) : v);
|
||||
if (t==='k8s') setK8sD(items); if (t==='node') setNodeD(items);
|
||||
if (t==='kubernetes') setK8sD(items); if (t==='node') setNodeD(items);
|
||||
if (t==='pod') setPodD(items); if (t==='jvm') setJvmD(items);
|
||||
} catch {}
|
||||
}
|
||||
@@ -175,12 +175,12 @@ export const PrometheusDashboard: React.FC<Props> = ({ dsUrl }) => {
|
||||
: (
|
||||
<Tabs value={tab} onValueChange={setTab}>
|
||||
<TabsList className="bg-[var(--dg-bg-tertiary)] mb-3">
|
||||
<TabsTrigger value="k8s" className="text-xs"><Container className="w-3 h-3 mr-1" />K8s</TabsTrigger>
|
||||
<TabsTrigger value="kubernetes" className="text-xs"><Container className="w-3 h-3 mr-1" />K8s</TabsTrigger>
|
||||
<TabsTrigger value="node" className="text-xs"><Server className="w-3 h-3 mr-1" />Node</TabsTrigger>
|
||||
<TabsTrigger value="pod" className="text-xs"><Box className="w-3 h-3 mr-1" />Pod</TabsTrigger>
|
||||
<TabsTrigger value="jvm" className="text-xs"><Zap className="w-3 h-3 mr-1" />JVM</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="k8s"><K8sPanel d={k8sD} /></TabsContent>
|
||||
<TabsContent value="kubernetes"><K8sPanel d={k8sD} /></TabsContent>
|
||||
<TabsContent value="node"><NodePanel d={nodeD} /></TabsContent>
|
||||
<TabsContent value="pod"><PodPanel d={podD} /></TabsContent>
|
||||
<TabsContent value="jvm"><JvmPanel d={jvmD} /></TabsContent>
|
||||
|
||||
@@ -156,100 +156,119 @@ export const serverApi = {
|
||||
};
|
||||
|
||||
// ==================== K8s 集群 API ====================
|
||||
export const k8sApi = {
|
||||
export const kubernetesApi = {
|
||||
getClusters: async () => {
|
||||
return http.get<ListResponse>('/k8s-clusters');
|
||||
return http.get<ListResponse>('/kubernetes-clusters');
|
||||
},
|
||||
getClusterDetail: async (id: number | string) => {
|
||||
return http.get(`/k8s-clusters/${id}/detail`);
|
||||
return http.get(`/kubernetes-clusters/${id}/detail`);
|
||||
},
|
||||
createCluster: async (data: any) => {
|
||||
return http.post('/k8s-clusters', data);
|
||||
return http.post('/kubernetes-clusters', data);
|
||||
},
|
||||
updateCluster: async (id: number | string, data: any) => {
|
||||
return http.put(`/k8s-clusters/${id}`, data);
|
||||
return http.put(`/kubernetes-clusters/${id}`, data);
|
||||
},
|
||||
deleteCluster: async (id: number | string) => {
|
||||
return http.delete(`/k8s-clusters/${id}`);
|
||||
return http.delete(`/kubernetes-clusters/${id}`);
|
||||
},
|
||||
getNodes: async (clusterId: number | string) => {
|
||||
return http.get(`/k8s-clusters/${clusterId}/nodes`);
|
||||
return http.get(`/kubernetes-clusters/${clusterId}/nodes`);
|
||||
},
|
||||
getPods: async (clusterId: number | string) => {
|
||||
return http.get(`/k8s-clusters/${clusterId}/pods`);
|
||||
return http.get(`/kubernetes-clusters/${clusterId}/pods`);
|
||||
},
|
||||
getDeployments: async (clusterId: number | string) => {
|
||||
return http.get(`/k8s-clusters/${clusterId}/deployments`);
|
||||
return http.get(`/kubernetes-clusters/${clusterId}/deployments`);
|
||||
},
|
||||
getServices: async (clusterId: number | string) => {
|
||||
return http.get(`/k8s-clusters/${clusterId}/services`);
|
||||
return http.get(`/kubernetes-clusters/${clusterId}/services`);
|
||||
},
|
||||
getIngresses: async (clusterId: number | string) => {
|
||||
return http.get(`/k8s-clusters/${clusterId}/ingresses`);
|
||||
return http.get(`/kubernetes-clusters/${clusterId}/ingresses`);
|
||||
},
|
||||
syncCluster: async (clusterId: number | string) => {
|
||||
return http.post(`/k8s-clusters/${clusterId}/sync`);
|
||||
return http.post(`/kubernetes-clusters/${clusterId}/sync`);
|
||||
},
|
||||
getTopology: async (clusterId: number | string) => { // Logan.Li
|
||||
return http.get(`/k8s-clusters/${clusterId}/topology`);
|
||||
return http.get(`/kubernetes-clusters/${clusterId}/topology`);
|
||||
},
|
||||
saveTopology: async (clusterId: number | string, layoutData: string) => { // Logan.Li
|
||||
return http.put(`/k8s-clusters/${clusterId}/topology`, { layout_data: layoutData });
|
||||
return http.put(`/kubernetes-clusters/${clusterId}/topology`, { layout_data: layoutData });
|
||||
},
|
||||
|
||||
// === 工作负载操作 (Logan.Li) ===
|
||||
getPodLogs: async (clusterId: number | string, namespace: string, podName: string, tail: number = 200, container?: string) => {
|
||||
// === 工作负载操作 (Logan.Li) - Kuboard-style routes ===
|
||||
getPodLogs: async (clusterCode: string, namespace: string, podName: string, tail: number = 200, container?: string) => {
|
||||
const params = new URLSearchParams({ tail: String(tail) });
|
||||
if (container) params.set('container', container);
|
||||
return http.get(`/k8s-clusters/${clusterId}/namespaces/${namespace}/pods/${podName}/logs?${params}`);
|
||||
return http.get(`/kubernetes/${clusterCode}/namespace/${namespace}/pods/${podName}/logs?${params}`);
|
||||
},
|
||||
execPod: async (clusterId: number | string, namespace: string, podName: string, command: string[], container?: string) => {
|
||||
return http.post(`/k8s-clusters/${clusterId}/namespaces/${namespace}/pods/${podName}/exec`, { command, container });
|
||||
execPod: async (clusterCode: string, namespace: string, podName: string, command: string[], container?: string) => {
|
||||
return http.post(`/kubernetes/${clusterCode}/namespace/${namespace}/pods/${podName}/exec`, { command, container });
|
||||
},
|
||||
scaleDeployment: async (clusterId: number | string, namespace: string, name: string, replicas: number) => {
|
||||
return http.post(`/k8s-clusters/${clusterId}/namespaces/${namespace}/deployments/${name}/scale`, { replicas });
|
||||
scaleDeployment: async (clusterCode: string, namespace: string, name: string, replicas: number) => {
|
||||
return http.post(`/kubernetes/${clusterCode}/namespace/${namespace}/deployments/${name}/scale`, { replicas });
|
||||
},
|
||||
restartDeployment: async (clusterId: number | string, namespace: string, name: string) => {
|
||||
return http.post(`/k8s-clusters/${clusterId}/namespaces/${namespace}/deployments/${name}/restart`);
|
||||
restartDeployment: async (clusterCode: string, namespace: string, name: string) => {
|
||||
return http.post(`/kubernetes/${clusterCode}/namespace/${namespace}/deployments/${name}/restart`);
|
||||
},
|
||||
updateDeploymentImage: async (clusterId: number | string, namespace: string, name: string, image: string, containerName?: string) => {
|
||||
return http.post(`/k8s-clusters/${clusterId}/namespaces/${namespace}/deployments/${name}/update-image`, { image, container_name: containerName });
|
||||
},
|
||||
deletePod: async (clusterId: number | string, namespace: string, name: string) => {
|
||||
return http.delete(`/k8s-clusters/${clusterId}/namespaces/${namespace}/pods/${name}`);
|
||||
updateDeploymentImage: async (clusterCode: string, namespace: string, name: string, image: string, containerName?: string) => {
|
||||
return http.post(`/kubernetes/${clusterCode}/namespace/${namespace}/deployments/${name}/update-image`, { image, container_name: containerName });
|
||||
},
|
||||
|
||||
// === HPA 管理 (Logan.Li) ===
|
||||
getHPAs: async (clusterId: number | string) => {
|
||||
return http.get(`/k8s-clusters/${clusterId}/hpas`);
|
||||
getHPAs: async (clusterCode: string, namespace?: string) => {
|
||||
if (namespace) return http.get(`/kubernetes/${clusterCode}/namespace/${namespace}/hpas`);
|
||||
return http.get(`/kubernetes-clusters/${clusterCode}/hpas`); // fallback old route
|
||||
},
|
||||
createHPA: async (clusterId: number | string, data: { name: string; namespace: string; targetKind: string; targetName: string; minReplicas: number; maxReplicas: number; cpuPercent: number; memPercent: number }) => {
|
||||
return http.post(`/k8s-clusters/${clusterId}/hpas`, data);
|
||||
createHPA: async (clusterCode: string, data: { name: string; namespace: string; targetKind: string; targetName: string; minReplicas: number; maxReplicas: number; cpuPercent: number; memPercent: number }) => {
|
||||
return http.post(`/kubernetes/${clusterCode}/namespace/${data.namespace}/hpas`, data);
|
||||
},
|
||||
deleteHPA: async (clusterId: number | string, namespace: string, name: string) => {
|
||||
return http.delete(`/k8s-clusters/${clusterId}/namespaces/${namespace}/hpas/${name}`);
|
||||
deleteHPA: async (clusterCode: string, namespace: string, name: string) => {
|
||||
return http.delete(`/kubernetes/${clusterCode}/namespace/${namespace}/hpas/${name}`);
|
||||
},
|
||||
|
||||
// === CronJob 管理 (Logan.Li) ===
|
||||
getCronJobs: async (clusterId: number | string) => {
|
||||
return http.get(`/k8s-clusters/${clusterId}/cronjobs`);
|
||||
getCronJobs: async (clusterCode: string, namespace?: string) => {
|
||||
if (namespace) return http.get(`/kubernetes/${clusterCode}/namespace/${namespace}/cronjobs`);
|
||||
return http.get(`/kubernetes-clusters/${clusterCode}/cronjobs`);
|
||||
},
|
||||
createCronJob: async (clusterId: number | string, data: { name: string; namespace: string; schedule: string; image: string; command: string[] }) => {
|
||||
return http.post(`/k8s-clusters/${clusterId}/cronjobs`, data);
|
||||
createCronJob: async (clusterCode: string, data: { name: string; namespace: string; schedule: string; image: string; command: string[] }) => {
|
||||
return http.post(`/kubernetes/${clusterCode}/namespace/${data.namespace}/cronjobs`, data);
|
||||
},
|
||||
suspendCronJob: async (clusterId: number | string, namespace: string, name: string, suspend: boolean) => {
|
||||
return http.post(`/k8s-clusters/${clusterId}/namespaces/${namespace}/cronjobs/${name}/suspend`, { suspend });
|
||||
suspendCronJob: async (clusterCode: string, namespace: string, name: string, suspend: boolean) => {
|
||||
return http.post(`/kubernetes/${clusterCode}/namespace/${namespace}/cronjobs/${name}/suspend`, { suspend });
|
||||
},
|
||||
triggerCronJob: async (clusterId: number | string, namespace: string, name: string) => {
|
||||
return http.post(`/k8s-clusters/${clusterId}/namespaces/${namespace}/cronjobs/${name}/trigger`);
|
||||
triggerCronJob: async (clusterCode: string, namespace: string, name: string) => {
|
||||
return http.post(`/kubernetes/${clusterCode}/namespace/${namespace}/cronjobs/${name}/trigger`);
|
||||
},
|
||||
deleteCronJob: async (clusterId: number | string, namespace: string, name: string) => {
|
||||
return http.delete(`/k8s-clusters/${clusterId}/namespaces/${namespace}/cronjobs/${name}`);
|
||||
deleteCronJob: async (clusterCode: string, namespace: string, name: string) => {
|
||||
return http.delete(`/kubernetes/${clusterCode}/namespace/${namespace}/cronjobs/${name}`);
|
||||
},
|
||||
|
||||
// === Namespace-scoped resources (Kuboard-style) ===
|
||||
getNamespaceDeployments: async (clusterCode: string, namespace: string) => {
|
||||
return http.get(`/kubernetes/${clusterCode}/namespace/${namespace}/deployments`);
|
||||
},
|
||||
getNamespacePods: async (clusterCode: string, namespace: string) => {
|
||||
return http.get(`/kubernetes/${clusterCode}/namespace/${namespace}/pods`);
|
||||
},
|
||||
getNamespaceServices: async (clusterCode: string, namespace: string) => {
|
||||
return http.get(`/kubernetes/${clusterCode}/namespace/${namespace}/services`);
|
||||
},
|
||||
getNamespaceIngresses: async (clusterCode: string, namespace: string) => {
|
||||
return http.get(`/kubernetes/${clusterCode}/namespace/${namespace}/ingresses`);
|
||||
},
|
||||
getNamespaceConfigMaps: async (clusterCode: string, namespace: string) => {
|
||||
return http.get(`/kubernetes/${clusterCode}/namespace/${namespace}/configmaps`);
|
||||
},
|
||||
getNamespaceSecrets: async (clusterCode: string, namespace: string) => {
|
||||
return http.get(`/kubernetes/${clusterCode}/namespace/${namespace}/secrets`);
|
||||
},
|
||||
|
||||
// === Namespace (Logan.Li) ===
|
||||
getNamespaces: async (clusterId: number | string) => {
|
||||
return http.get(`/k8s-clusters/${clusterId}/namespaces`);
|
||||
getNamespaces: async (clusterCode: string) => {
|
||||
return http.get(`/kubernetes/${clusterCode}/namespaces`);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ export interface Server {
|
||||
}
|
||||
|
||||
// Kubernetes集群
|
||||
export interface K8sCluster {
|
||||
export interface KubernetesCluster {
|
||||
id: string;
|
||||
name: string;
|
||||
version: string;
|
||||
@@ -34,7 +34,7 @@ export interface K8sCluster {
|
||||
}
|
||||
|
||||
// K8s节点
|
||||
export interface K8sNode {
|
||||
export interface KubernetesNode {
|
||||
id: string;
|
||||
name: string;
|
||||
clusterId: string;
|
||||
@@ -51,7 +51,7 @@ export interface K8sNode {
|
||||
}
|
||||
|
||||
// K8s Pod
|
||||
export interface K8sPod {
|
||||
export interface KubernetesPod {
|
||||
id: string;
|
||||
name: string;
|
||||
namespace: string;
|
||||
|
||||
Reference in new issue
Block a user