feat: 新增日志中心、功能优化与代码重构
- 新增 log_datasource.go / log_proxy.go / user_api_token.go 后端控制器 - 新增 log_datasource.go model - 新增 monitor/log-center.ts API 模块 - 新增 LogCenter 前端组件及页面 - 重构 deployment 相关组件 (HPDA/UpdateImageModal/bundle-yaml 等) - 新增 ResetPasswordDialog / code-snippet-block / copy-button 等 UI 组件 - 重构多个 k8s 相关组件 (TopologyView/ResourceVisualEditor/PodFileBrowser 等) - 更新多个 API 和工具函数 (auth.ts/monitor/index.ts/request.ts 等) - 更新静态资源 (index.html + 新 JS/CSS bundle) - 删除废弃静态资源文件
This commit is contained in:
1 parent
5ca0e6d83a
commit
8d46e8f352
197 files changed
+5014
-815
No files matched your search
@@ -0,0 +1,100 @@
|
||||
// Deployment 多文档 YAML(Deployment + 关联 Service)加载与保存 // Logan.Li
|
||||
import { kubernetesApi } from '@/api';
|
||||
import {
|
||||
manifestToEditableYaml,
|
||||
parseEditableManifest,
|
||||
parseEditableManifests,
|
||||
prepareManifestForSave,
|
||||
} from './k8s-manifest-utils';
|
||||
|
||||
const toArray = (v: unknown) => (Array.isArray(v) ? v : ((v as Record<string, any>)?.list || (v as Record<string, any>)?.items || (v as Record<string, any>)?.data || []));
|
||||
|
||||
/** Service selector 是否匹配 Deployment 标签 // Logan.Li */
|
||||
export function selectorMatches(
|
||||
depSelector: Record<string, string>,
|
||||
svcSelector: Record<string, string>,
|
||||
): boolean {
|
||||
if (Object.keys(svcSelector).length === 0) return false;
|
||||
return Object.entries(svcSelector).every(([k, v]) => depSelector[k] === v);
|
||||
}
|
||||
|
||||
/** 查找与 Deployment 关联的 Service 名称 // Logan.Li */
|
||||
export function findMatchedServiceNames(
|
||||
deploymentName: string,
|
||||
depSelector: Record<string, string>,
|
||||
services: any[],
|
||||
): string[] {
|
||||
const names = new Set<string>();
|
||||
for (const svc of services) {
|
||||
const svcName = svc.name || svc.metadata?.name || '';
|
||||
if (!svcName) continue;
|
||||
const svcSelector = svc.spec?.selector || svc.selector || {};
|
||||
if (svcName === deploymentName || selectorMatches(depSelector, svcSelector)) {
|
||||
names.add(svcName);
|
||||
}
|
||||
}
|
||||
return [...names].sort();
|
||||
}
|
||||
|
||||
/** 加载 Deployment + 关联 Service 的多文档 YAML // Logan.Li */
|
||||
export async function loadDeploymentBundleYaml(
|
||||
clusterCode: string,
|
||||
namespace: string,
|
||||
deploymentName: string,
|
||||
): Promise<string> {
|
||||
const depYaml = await kubernetesApi.getResourceYaml(clusterCode, namespace, 'deployments', deploymentName);
|
||||
const { manifest: depManifest } = await parseEditableManifest(depYaml);
|
||||
const depSelector = depManifest?.spec?.selector?.matchLabels
|
||||
|| depManifest?.spec?.template?.metadata?.labels
|
||||
|| {};
|
||||
|
||||
const svcListRes = await kubernetesApi.getNamespaceServices(clusterCode, namespace).catch(() => []);
|
||||
const matchedSvcNames = findMatchedServiceNames(deploymentName, depSelector, toArray(svcListRes));
|
||||
|
||||
const docs: string[] = [];
|
||||
if (depManifest) {
|
||||
docs.push(await manifestToEditableYaml(depManifest));
|
||||
} else {
|
||||
const { yaml: stripped } = await parseEditableManifest(depYaml);
|
||||
if (stripped.trim()) docs.push(stripped);
|
||||
}
|
||||
|
||||
for (const svcName of matchedSvcNames) {
|
||||
try {
|
||||
const svcYaml = await kubernetesApi.getResourceYaml(clusterCode, namespace, 'services', svcName);
|
||||
const { yaml: stripped } = await parseEditableManifest(svcYaml);
|
||||
if (stripped.trim()) docs.push(stripped);
|
||||
} catch {
|
||||
// 单个 Service 拉取失败时跳过 // Logan.Li
|
||||
}
|
||||
}
|
||||
|
||||
return docs.join('\n---\n');
|
||||
}
|
||||
|
||||
/** 保存多文档 YAML(Deployment + Service 等)// Logan.Li */
|
||||
export async function saveDeploymentBundleYaml(
|
||||
clusterCode: string,
|
||||
namespace: string,
|
||||
yamlText: string,
|
||||
): Promise<void> {
|
||||
const { manifests } = await parseEditableManifests(yamlText);
|
||||
if (manifests.length === 0) throw new Error('YAML 内容为空或解析失败');
|
||||
|
||||
for (const manifest of manifests) {
|
||||
const kind = String(manifest.kind || '').toLowerCase();
|
||||
const name = String(manifest.metadata?.name || '').trim();
|
||||
if (!kind || !name) throw new Error('每个 YAML 文档必须包含 kind 和 metadata.name');
|
||||
|
||||
const docYaml = await prepareManifestForSave(manifest);
|
||||
if (kind === 'deployment') {
|
||||
await kubernetesApi.updateResourceYaml(clusterCode, namespace, 'deployments', name, docYaml);
|
||||
continue;
|
||||
}
|
||||
if (kind === 'service') {
|
||||
await kubernetesApi.applyYAML(clusterCode, docYaml);
|
||||
continue;
|
||||
}
|
||||
throw new Error(`不支持的资源类型: ${manifest.kind}(仅支持 Deployment / Service)`);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user