/* eslint-disable @typescript-eslint/no-explicit-any */ // Deployment 多文档 YAML(Deployment + 关联 Service)加载与保存 // Logan.Li import { kubernetesApi } from '@/api'; import i18n from '@/i18n'; import { manifestToEditableYaml, parseEditableManifest, parseEditableManifests, prepareManifestForSave, } from './k8s-manifest-utils'; const toArray = (v: unknown) => (Array.isArray(v) ? v : ((v as Record)?.list || (v as Record)?.items || (v as Record)?.data || [])); /** Service selector 是否匹配 Deployment 标签 // Logan.Li */ export function selectorMatches( depSelector: Record, svcSelector: Record, ): 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, services: any[], ): string[] { const names = new Set(); 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 { 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 { const { manifests } = await parseEditableManifests(yamlText); if (manifests.length === 0) throw new Error(i18n.t('kubernetes.deploymentbundl.s47161e05')); for (const manifest of manifests) { const kind = String(manifest.kind || '').toLowerCase(); const name = String(manifest.metadata?.name || '').trim(); if (!kind || !name) throw new Error(i18n.t('kubernetes.deploymentbundl.s659c1bb5')); 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)`); } }