From be6b6d75ac0648f5b396dc5145a31f002f93e4dc Mon Sep 17 00:00:00 2001 From: dengqichen Date: Sat, 13 Dec 2025 13:40:35 +0800 Subject: [PATCH] =?UTF-8?q?1.30=20k8s=20pods=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/K8sDeploymentApiController.java | 22 ++ .../integration/IK8sServiceIntegration.java | 30 ++ .../impl/K8sServiceIntegrationImpl.java | 268 ++++++++++++++++++ .../integration/response/K8sPodResponse.java | 180 ++++++++++++ .../deploy/service/IK8sPodService.java | 56 ++++ .../service/impl/K8sPodServiceImpl.java | 132 +++++++++ 6 files changed, 688 insertions(+) create mode 100644 backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/response/K8sPodResponse.java create mode 100644 backend/src/main/java/com/qqchen/deploy/backend/deploy/service/IK8sPodService.java create mode 100644 backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/K8sPodServiceImpl.java diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/K8sDeploymentApiController.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/K8sDeploymentApiController.java index f4dbef67..8d2d2b16 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/K8sDeploymentApiController.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/K8sDeploymentApiController.java @@ -2,8 +2,10 @@ package com.qqchen.deploy.backend.deploy.api; import com.qqchen.deploy.backend.deploy.dto.K8sDeploymentDTO; import com.qqchen.deploy.backend.deploy.entity.K8sDeployment; +import com.qqchen.deploy.backend.deploy.integration.response.K8sPodResponse; import com.qqchen.deploy.backend.deploy.query.K8sDeploymentQuery; import com.qqchen.deploy.backend.deploy.service.IK8sDeploymentService; +import com.qqchen.deploy.backend.deploy.service.IK8sPodService; import com.qqchen.deploy.backend.framework.api.Response; import com.qqchen.deploy.backend.framework.controller.BaseController; import io.swagger.v3.oas.annotations.Operation; @@ -29,6 +31,9 @@ public class K8sDeploymentApiController extends BaseController create(@Validated @RequestBody K8sDeploymentDTO dto) { return super.create(dto); @@ -99,6 +104,23 @@ public class K8sDeploymentApiController extends BaseController> getDeploymentPods( + @Parameter(description = "Deployment ID", required = true) @PathVariable Long deploymentId + ) { + return Response.success(k8sPodService.listPodsByDeployment(deploymentId)); + } + + @Operation(summary = "查询Pod详情", description = "查询指定Pod的详细信息") + @GetMapping("/{deploymentId}/pods/{podName}") + public Response getPodDetail( + @Parameter(description = "Deployment ID", required = true) @PathVariable Long deploymentId, + @Parameter(description = "Pod名称", required = true) @PathVariable String podName + ) { + return Response.success(k8sPodService.getPodDetailByDeployment(deploymentId, podName)); + } + @Override protected void exportData(HttpServletResponse response, List data) { log.info("导出K8S Deployment数据,数据量:{}", data.size()); diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/IK8sServiceIntegration.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/IK8sServiceIntegration.java index a686cb56..ac04c442 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/IK8sServiceIntegration.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/IK8sServiceIntegration.java @@ -3,6 +3,7 @@ package com.qqchen.deploy.backend.deploy.integration; import com.qqchen.deploy.backend.deploy.entity.ExternalSystem; import com.qqchen.deploy.backend.deploy.integration.response.K8sDeploymentResponse; import com.qqchen.deploy.backend.deploy.integration.response.K8sNamespaceResponse; +import com.qqchen.deploy.backend.deploy.integration.response.K8sPodResponse; import com.qqchen.deploy.backend.system.enums.ExternalSystemTypeEnum; import java.util.List; @@ -45,6 +46,35 @@ public interface IK8sServiceIntegration extends IExternalSystemIntegration { */ List listAllDeployments(ExternalSystem externalSystem); + /** + * 查询指定命名空间下的所有Pod + * + * @param externalSystem K8S系统配置 + * @param namespace 命名空间名称 + * @return Pod列表 + */ + List listPods(ExternalSystem externalSystem, String namespace); + + /** + * 查询指定Deployment下的所有Pod + * + * @param externalSystem K8S系统配置 + * @param namespace 命名空间名称 + * @param deploymentName Deployment名称 + * @return Pod列表 + */ + List listPodsByDeployment(ExternalSystem externalSystem, String namespace, String deploymentName); + + /** + * 查询单个Pod详情 + * + * @param externalSystem K8S系统配置 + * @param namespace 命名空间名称 + * @param podName Pod名称 + * @return Pod详情 + */ + K8sPodResponse getPod(ExternalSystem externalSystem, String namespace, String podName); + /** * 获取系统类型 * diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/impl/K8sServiceIntegrationImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/impl/K8sServiceIntegrationImpl.java index f02b67e3..883265d2 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/impl/K8sServiceIntegrationImpl.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/impl/K8sServiceIntegrationImpl.java @@ -5,6 +5,7 @@ import com.qqchen.deploy.backend.framework.utils.JsonUtils; import com.qqchen.deploy.backend.deploy.integration.IK8sServiceIntegration; import com.qqchen.deploy.backend.deploy.integration.response.K8sDeploymentResponse; import com.qqchen.deploy.backend.deploy.integration.response.K8sNamespaceResponse; +import com.qqchen.deploy.backend.deploy.integration.response.K8sPodResponse; import com.qqchen.deploy.backend.framework.enums.ResponseCode; import com.qqchen.deploy.backend.framework.exception.BusinessException; import com.qqchen.deploy.backend.system.enums.ExternalSystemTypeEnum; @@ -317,6 +318,273 @@ public class K8sServiceIntegrationImpl extends BaseExternalSystemIntegration imp } } + /** + * 查询指定命名空间下的所有Pod + */ + @Override + public List listPods(ExternalSystem externalSystem, String namespace) { + log.info("查询K8S Pod,集群: {}, 命名空间: {}", externalSystem.getName(), namespace); + + try { + K8sApiClientCache cache = getApiClientCache(externalSystem); + CoreV1Api api = new CoreV1Api(cache.apiClient); + + V1PodList podList = api.listNamespacedPod( + namespace, null, null, null, null, null, null, null, null, null, null + ); + + List pods = new ArrayList<>(); + for (V1Pod pod : podList.getItems()) { + pods.add(convertPodToResponse(pod)); + } + + log.info("查询到 {} 个Pod", pods.size()); + return pods; + + } catch (Exception e) { + log.error("查询K8S Pod失败,集群: {}, 命名空间: {}, 错误: {}", + externalSystem.getName(), namespace, e.getMessage(), e); + throw new BusinessException(ResponseCode.K8S_OPERATION_FAILED); + } + } + + /** + * 查询指定Deployment下的所有Pod + */ + @Override + public List listPodsByDeployment(ExternalSystem externalSystem, String namespace, String deploymentName) { + log.info("查询K8S Deployment的Pod,集群: {}, 命名空间: {}, Deployment: {}", + externalSystem.getName(), namespace, deploymentName); + + try { + K8sApiClientCache cache = getApiClientCache(externalSystem); + + // 1. 先查询Deployment获取selector + AppsV1Api appsApi = new AppsV1Api(cache.apiClient); + V1Deployment deployment = appsApi.readNamespacedDeployment(deploymentName, namespace, null); + + if (deployment.getSpec() == null || deployment.getSpec().getSelector() == null + || deployment.getSpec().getSelector().getMatchLabels() == null) { + log.warn("Deployment没有selector: {}/{}", namespace, deploymentName); + return new ArrayList<>(); + } + + // 2. 构建label selector + Map matchLabels = deployment.getSpec().getSelector().getMatchLabels(); + String labelSelector = matchLabels.entrySet().stream() + .map(entry -> entry.getKey() + "=" + entry.getValue()) + .reduce((a, b) -> a + "," + b) + .orElse(""); + + // 3. 使用label selector查询Pod + CoreV1Api coreApi = new CoreV1Api(cache.apiClient); + V1PodList podList = coreApi.listNamespacedPod( + namespace, null, null, null, null, labelSelector, null, null, null, null, null + ); + + List pods = new ArrayList<>(); + for (V1Pod pod : podList.getItems()) { + pods.add(convertPodToResponse(pod)); + } + + log.info("查询到 {} 个Pod", pods.size()); + return pods; + + } catch (ApiException e) { + if (e.getCode() == 404) { + log.warn("Deployment不存在: {}/{}", namespace, deploymentName); + throw new BusinessException(ResponseCode.K8S_RESOURCE_NOT_FOUND); + } + log.error("查询K8S Deployment的Pod失败,集群: {}, 命名空间: {}, Deployment: {}, 错误: {}", + externalSystem.getName(), namespace, deploymentName, e.getMessage(), e); + throw new BusinessException(ResponseCode.K8S_OPERATION_FAILED); + } catch (Exception e) { + log.error("查询K8S Deployment的Pod失败,集群: {}, 命名空间: {}, Deployment: {}, 错误: {}", + externalSystem.getName(), namespace, deploymentName, e.getMessage(), e); + throw new BusinessException(ResponseCode.K8S_OPERATION_FAILED); + } + } + + /** + * 查询单个Pod详情 + */ + @Override + public K8sPodResponse getPod(ExternalSystem externalSystem, String namespace, String podName) { + log.info("查询K8S Pod详情,集群: {}, 命名空间: {}, Pod: {}", + externalSystem.getName(), namespace, podName); + + try { + K8sApiClientCache cache = getApiClientCache(externalSystem); + CoreV1Api api = new CoreV1Api(cache.apiClient); + + V1Pod pod = api.readNamespacedPod(podName, namespace, null); + + return convertPodToResponse(pod); + + } catch (ApiException e) { + if (e.getCode() == 404) { + log.warn("Pod不存在: {}/{}", namespace, podName); + throw new BusinessException(ResponseCode.K8S_POD_NOT_FOUND); + } + log.error("查询K8S Pod详情失败,集群: {}, 命名空间: {}, Pod: {}, 错误: {}", + externalSystem.getName(), namespace, podName, e.getMessage(), e); + throw new BusinessException(ResponseCode.K8S_OPERATION_FAILED); + } catch (Exception e) { + log.error("查询K8S Pod详情失败,集群: {}, 命名空间: {}, Pod: {}, 错误: {}", + externalSystem.getName(), namespace, podName, e.getMessage(), e); + throw new BusinessException(ResponseCode.K8S_OPERATION_FAILED); + } + } + + /** + * 将K8S Pod对象转换为响应对象 + */ + private K8sPodResponse convertPodToResponse(V1Pod pod) { + K8sPodResponse response = new K8sPodResponse(); + + // 基本信息 + response.setName(pod.getMetadata().getName()); + response.setNamespace(pod.getMetadata().getNamespace()); + response.setLabels(pod.getMetadata().getLabels()); + response.setAnnotations(pod.getMetadata().getAnnotations()); + + // 时间信息 + if (pod.getMetadata().getCreationTimestamp() != null) { + response.setCreationTimestamp( + LocalDateTime.ofInstant( + pod.getMetadata().getCreationTimestamp().toInstant(), + ZoneId.systemDefault() + ) + ); + } + + // 状态信息 + if (pod.getStatus() != null) { + response.setPhase(pod.getStatus().getPhase()); + response.setReason(pod.getStatus().getReason()); + response.setMessage(pod.getStatus().getMessage()); + response.setPodIP(pod.getStatus().getPodIP()); + response.setHostIP(pod.getStatus().getHostIP()); + + if (pod.getStatus().getStartTime() != null) { + response.setStartTime( + LocalDateTime.ofInstant( + pod.getStatus().getStartTime().toInstant(), + ZoneId.systemDefault() + ) + ); + } + + // 容器状态 + if (pod.getStatus().getContainerStatuses() != null) { + List containers = new ArrayList<>(); + int totalRestartCount = 0; + boolean allReady = true; + + for (V1ContainerStatus containerStatus : pod.getStatus().getContainerStatuses()) { + K8sPodResponse.ContainerInfo containerInfo = new K8sPodResponse.ContainerInfo(); + containerInfo.setName(containerStatus.getName()); + containerInfo.setImage(containerStatus.getImage()); + containerInfo.setImageID(containerStatus.getImageID()); + containerInfo.setReady(containerStatus.getReady()); + containerInfo.setRestartCount(containerStatus.getRestartCount()); + containerInfo.setContainerID(containerStatus.getContainerID()); + + totalRestartCount += containerStatus.getRestartCount(); + if (!containerStatus.getReady()) { + allReady = false; + } + + // 容器状态 + V1ContainerState state = containerStatus.getState(); + if (state != null) { + if (state.getRunning() != null) { + containerInfo.setState("running"); + if (state.getRunning().getStartedAt() != null) { + containerInfo.setStartedAt( + LocalDateTime.ofInstant( + state.getRunning().getStartedAt().toInstant(), + ZoneId.systemDefault() + ) + ); + } + } else if (state.getWaiting() != null) { + containerInfo.setState("waiting"); + containerInfo.setStateReason(state.getWaiting().getReason()); + containerInfo.setStateMessage(state.getWaiting().getMessage()); + } else if (state.getTerminated() != null) { + containerInfo.setState("terminated"); + containerInfo.setStateReason(state.getTerminated().getReason()); + containerInfo.setStateMessage(state.getTerminated().getMessage()); + } + } + + containers.add(containerInfo); + } + + response.setContainers(containers); + response.setRestartCount(totalRestartCount); + response.setReady(allReady); + } + } + + // Spec信息 + if (pod.getSpec() != null) { + response.setNodeName(pod.getSpec().getNodeName()); + + // 容器资源配置 + if (pod.getSpec().getContainers() != null && response.getContainers() != null) { + for (int i = 0; i < pod.getSpec().getContainers().size() && i < response.getContainers().size(); i++) { + V1Container container = pod.getSpec().getContainers().get(i); + K8sPodResponse.ContainerInfo containerInfo = response.getContainers().get(i); + + if (container.getResources() != null) { + if (container.getResources().getRequests() != null) { + containerInfo.setCpuRequest( + container.getResources().getRequests().get("cpu") != null + ? container.getResources().getRequests().get("cpu").toSuffixedString() + : null + ); + containerInfo.setMemoryRequest( + container.getResources().getRequests().get("memory") != null + ? container.getResources().getRequests().get("memory").toSuffixedString() + : null + ); + } + if (container.getResources().getLimits() != null) { + containerInfo.setCpuLimit( + container.getResources().getLimits().get("cpu") != null + ? container.getResources().getLimits().get("cpu").toSuffixedString() + : null + ); + containerInfo.setMemoryLimit( + container.getResources().getLimits().get("memory") != null + ? container.getResources().getLimits().get("memory").toSuffixedString() + : null + ); + } + } + } + } + } + + // Owner信息 + if (pod.getMetadata().getOwnerReferences() != null && !pod.getMetadata().getOwnerReferences().isEmpty()) { + V1OwnerReference owner = pod.getMetadata().getOwnerReferences().get(0); + response.setOwnerKind(owner.getKind()); + response.setOwnerName(owner.getName()); + } + + // 序列化为YAML + try { + response.setYamlConfig(Yaml.dump(pod)); + } catch (Exception e) { + log.warn("序列化Pod为YAML失败: {}", pod.getMetadata().getName(), e); + } + + return response; + } + /** * 创建K8S ApiClient(对外接口,使用缓存) * diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/response/K8sPodResponse.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/response/K8sPodResponse.java new file mode 100644 index 00000000..0cd95e1e --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/response/K8sPodResponse.java @@ -0,0 +1,180 @@ +package com.qqchen.deploy.backend.deploy.integration.response; + +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +/** + * K8S Pod响应对象 + */ +@Data +public class K8sPodResponse { + + /** + * Pod名称 + */ + private String name; + + /** + * 命名空间 + */ + private String namespace; + + /** + * Pod状态阶段(Running, Pending, Succeeded, Failed, Unknown) + */ + private String phase; + + /** + * Pod状态原因 + */ + private String reason; + + /** + * Pod状态消息 + */ + private String message; + + /** + * Pod IP地址 + */ + private String podIP; + + /** + * 宿主机IP + */ + private String hostIP; + + /** + * 节点名称 + */ + private String nodeName; + + /** + * 容器列表 + */ + private List containers; + + /** + * 重启次数(所有容器的总和) + */ + private Integer restartCount; + + /** + * 创建时间 + */ + private LocalDateTime creationTimestamp; + + /** + * 启动时间 + */ + private LocalDateTime startTime; + + /** + * 标签 + */ + private Map labels; + + /** + * 注解 + */ + private Map annotations; + + /** + * 所属控制器类型(Deployment, StatefulSet, DaemonSet等) + */ + private String ownerKind; + + /** + * 所属控制器名称 + */ + private String ownerName; + + /** + * 是否就绪 + */ + private Boolean ready; + + /** + * YAML配置 + */ + private String yamlConfig; + + /** + * 容器信息 + */ + @Data + public static class ContainerInfo { + /** + * 容器名称 + */ + private String name; + + /** + * 镜像 + */ + private String image; + + /** + * 镜像ID + */ + private String imageID; + + /** + * 容器状态(running, waiting, terminated) + */ + private String state; + + /** + * 是否就绪 + */ + private Boolean ready; + + /** + * 重启次数 + */ + private Integer restartCount; + + /** + * 容器ID + */ + private String containerID; + + /** + * 启动时间 + */ + private LocalDateTime startedAt; + + /** + * CPU请求 + */ + private String cpuRequest; + + /** + * CPU限制 + */ + private String cpuLimit; + + /** + * 内存请求 + */ + private String memoryRequest; + + /** + * 内存限制 + */ + private String memoryLimit; + + /** + * 状态原因(如果是waiting或terminated状态) + */ + private String stateReason; + + /** + * 状态消息 + */ + private String stateMessage; + } +} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/IK8sPodService.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/IK8sPodService.java new file mode 100644 index 00000000..632357e8 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/IK8sPodService.java @@ -0,0 +1,56 @@ +package com.qqchen.deploy.backend.deploy.service; + +import com.qqchen.deploy.backend.deploy.integration.response.K8sPodResponse; + +import java.util.List; + +/** + * K8S Pod服务接口 + */ +public interface IK8sPodService { + + /** + * 根据K8sDeployment ID查询Pod列表 + * + * @param deploymentId K8sDeployment ID + * @return Pod列表 + */ + List listPodsByDeployment(Long deploymentId); + + /** + * 根据K8s信息查询Pod列表 + * + * @param externalSystemId K8S集群ID + * @param namespaceId 命名空间ID + * @param deploymentName Deployment名称 + * @return Pod列表 + */ + List listPodsByDeploymentInfo(Long externalSystemId, Long namespaceId, String deploymentName); + + /** + * 查询Pod详情 + * + * @param externalSystemId K8S集群ID + * @param namespace 命名空间名称 + * @param podName Pod名称 + * @return Pod详情 + */ + K8sPodResponse getPodDetail(Long externalSystemId, String namespace, String podName); + + /** + * 根据DeploymentId查询Pod详情 + * + * @param deploymentId Deployment ID + * @param podName Pod名称 + * @return Pod详情 + */ + K8sPodResponse getPodDetailByDeployment(Long deploymentId, String podName); + + /** + * 根据命名空间ID查询所有Pod + * + * @param namespaceId 命名空间ID + * @return Pod列表 + */ + List listPodsByNamespace(Long namespaceId); +} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/K8sPodServiceImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/K8sPodServiceImpl.java new file mode 100644 index 00000000..084d8757 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/K8sPodServiceImpl.java @@ -0,0 +1,132 @@ +package com.qqchen.deploy.backend.deploy.service.impl; + +import com.qqchen.deploy.backend.deploy.entity.ExternalSystem; +import com.qqchen.deploy.backend.deploy.entity.K8sDeployment; +import com.qqchen.deploy.backend.deploy.entity.K8sNamespace; +import com.qqchen.deploy.backend.deploy.integration.IK8sServiceIntegration; +import com.qqchen.deploy.backend.deploy.integration.response.K8sPodResponse; +import com.qqchen.deploy.backend.deploy.repository.IExternalSystemRepository; +import com.qqchen.deploy.backend.deploy.repository.IK8sDeploymentRepository; +import com.qqchen.deploy.backend.deploy.repository.IK8sNamespaceRepository; +import com.qqchen.deploy.backend.deploy.service.IK8sPodService; +import com.qqchen.deploy.backend.framework.enums.ResponseCode; +import com.qqchen.deploy.backend.framework.exception.BusinessException; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * K8S Pod服务实现 + */ +@Slf4j +@Service +public class K8sPodServiceImpl implements IK8sPodService { + + @Resource + private IK8sDeploymentRepository k8sDeploymentRepository; + + @Resource + private IK8sNamespaceRepository k8sNamespaceRepository; + + @Resource + private IExternalSystemRepository externalSystemRepository; + + @Resource + private IK8sServiceIntegration k8sServiceIntegration; + + @Override + public List listPodsByDeployment(Long deploymentId) { + log.info("查询K8sDeployment的Pod列表,deploymentId: {}", deploymentId); + + // 1. 查询K8sDeployment + K8sDeployment deployment = k8sDeploymentRepository.findById(deploymentId) + .orElseThrow(() -> new BusinessException(ResponseCode.K8S_RESOURCE_NOT_FOUND)); + + // 2. 查询K8sNamespace + K8sNamespace namespace = k8sNamespaceRepository.findById(deployment.getNamespaceId()) + .orElseThrow(() -> new BusinessException(ResponseCode.K8S_RESOURCE_NOT_FOUND)); + + // 3. 查询ExternalSystem + ExternalSystem externalSystem = externalSystemRepository.findById(deployment.getExternalSystemId()) + .orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND)); + + // 4. 调用K8s API查询Pod + return k8sServiceIntegration.listPodsByDeployment( + externalSystem, + namespace.getNamespaceName(), + deployment.getDeploymentName() + ); + } + + @Override + public List listPodsByDeploymentInfo(Long externalSystemId, Long namespaceId, String deploymentName) { + log.info("根据K8s信息查询Pod列表,externalSystemId: {}, namespaceId: {}, deploymentName: {}", + externalSystemId, namespaceId, deploymentName); + + // 1. 查询K8sNamespace + K8sNamespace namespace = k8sNamespaceRepository.findById(namespaceId) + .orElseThrow(() -> new BusinessException(ResponseCode.K8S_RESOURCE_NOT_FOUND)); + + // 2. 查询ExternalSystem + ExternalSystem externalSystem = externalSystemRepository.findById(externalSystemId) + .orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND)); + + // 3. 调用K8s API查询Pod + return k8sServiceIntegration.listPodsByDeployment( + externalSystem, + namespace.getNamespaceName(), + deploymentName + ); + } + + @Override + public K8sPodResponse getPodDetail(Long externalSystemId, String namespace, String podName) { + log.info("查询Pod详情,externalSystemId: {}, namespace: {}, podName: {}", + externalSystemId, namespace, podName); + + // 1. 查询ExternalSystem + ExternalSystem externalSystem = externalSystemRepository.findById(externalSystemId) + .orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND)); + + // 2. 调用K8s API查询Pod详情 + return k8sServiceIntegration.getPod(externalSystem, namespace, podName); + } + + @Override + public List listPodsByNamespace(Long namespaceId) { + log.info("查询命名空间的所有Pod,namespaceId: {}", namespaceId); + + // 1. 查询K8sNamespace + K8sNamespace namespace = k8sNamespaceRepository.findById(namespaceId) + .orElseThrow(() -> new BusinessException(ResponseCode.K8S_RESOURCE_NOT_FOUND)); + + // 2. 查询ExternalSystem + ExternalSystem externalSystem = externalSystemRepository.findById(namespace.getExternalSystemId()) + .orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND)); + + // 3. 调用K8s API查询Pod + return k8sServiceIntegration.listPods(externalSystem, namespace.getNamespaceName()); + } + + @Override + public K8sPodResponse getPodDetailByDeployment(Long deploymentId, String podName) { + log.info("根据DeploymentId查询Pod详情,deploymentId: {}, podName: {}", deploymentId, podName); + + // 1. 查询K8sDeployment + K8sDeployment deployment = k8sDeploymentRepository.findById(deploymentId) + .orElseThrow(() -> new BusinessException(ResponseCode.K8S_RESOURCE_NOT_FOUND)); + + // 2. 查询K8sNamespace + K8sNamespace namespace = k8sNamespaceRepository.findById(deployment.getNamespaceId()) + .orElseThrow(() -> new BusinessException(ResponseCode.K8S_RESOURCE_NOT_FOUND)); + + // 3. 查询ExternalSystem + ExternalSystem externalSystem = externalSystemRepository.findById(deployment.getExternalSystemId()) + .orElseThrow(() -> new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND)); + + // 4. 调用K8s API查询Pod详情 + return k8sServiceIntegration.getPod(externalSystem, namespace.getNamespaceName(), podName); + } +}