| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- package nju.seec.SEECdemo.logic.service.impl;
- import nju.seec.SEECdemo.logic.api.k8s.*;
- import nju.seec.SEECdemo.logic.api.k8s.model.Deployment;
- import nju.seec.SEECdemo.logic.api.k8s.model.DeploymentStatus;
- import nju.seec.SEECdemo.logic.api.k8s.model.Ingress;
- import nju.seec.SEECdemo.logic.api.k8s.model.Service;
- import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
- import nju.seec.SEECdemo.logic.api.k8s.util.SecretTypeEnum;
- import nju.seec.SEECdemo.logic.api.k8s.vo.SecretVO;
- import nju.seec.SEECdemo.logic.service.ApplicationService;
- import nju.seec.SEECdemo.logic.vo.ApplicationStatusVO;
- import nju.seec.SEECdemo.logic.vo.ApplicationVO;
- import nju.seec.SEECdemo.util.LoggerUtil;
- import nju.seec.SEECdemo.web.dto.ApplicationDTO;
- import nju.seec.SEECdemo.web.dto.ContainerDTO;
- import nju.seec.SEECdemo.web.dto.PortDTO;
- import org.slf4j.Logger;
- import org.springframework.beans.factory.annotation.Autowired;
- import java.util.*;
- import java.util.stream.Collectors;
- @org.springframework.stereotype.Service
- public class ApplicationServiceImpl implements ApplicationService{
- private static final Logger logger = LoggerUtil.getLogger(ApplicationServiceImpl.class);
- @Autowired
- private DeploymentApi deploymentApi;
- @Autowired
- private ServiceApi serviceApi;
- @Autowired
- private NamespaceApi namespaceApi;
- @Autowired
- private SecretApi secretApi;
- @Autowired
- private IngressApi ingressApi;
- @Override
- public ApplicationVO create(ApplicationDTO applicationDTO) {
- return null;
- }
- @Override
- public void delete(String projectName, String name) {
- ingressApi.deleteIfExists(projectName, name);
- serviceApi.deleteIfExists(projectName, name);
- deploymentApi.deleteIfExist(projectName, name);
- }
- @Override
- public ApplicationVO update(ApplicationDTO applicationDTO) {
- return null;
- }
- @Override
- public ApplicationVO getByName(String projectName, String name) {
- Deployment deployment = deploymentApi.get(projectName, name);
- if (deployment == null){
- //抛出异常
- }
- return null;
- }
- @Override
- public ApplicationVO deploy(ApplicationDTO applicationDTO) {
- String projectName = applicationDTO.getProjectName();
- if (!namespaceApi.exists(projectName)) {
- //抛出项目不存在异常
- return null;
- }
- try {
- //删除现有的同名deployment
- deploymentApi.deleteIfExist(applicationDTO.getProjectName(), applicationDTO.getName());
- Deployment deployment = buildDeployment(applicationDTO);
- deploymentApi.createAsync(deployment);
- //删除现有的同名Service
- serviceApi.deleteIfExists(applicationDTO.getProjectName(), applicationDTO.getName());
- Service service = buildService(applicationDTO);
- serviceApi.create(service);
- //删除现有的同名Ingress
- ingressApi.deleteIfExists(applicationDTO.getProjectName(), applicationDTO.getName());
- Ingress ingress = buildIngress(applicationDTO);
- ingressApi.create(ingress);
- //构建返回数据
- return buildApplicationVO(applicationDTO, deployment, ingress);
- } catch (K8sApiException e) {
- //抛出创建失败异常
- deploymentApi.deleteIfExist(applicationDTO.getProjectName(), applicationDTO.getName());
- serviceApi.deleteIfExists(applicationDTO.getProjectName(), applicationDTO.getName());
- ingressApi.deleteIfExists(applicationDTO.getProjectName(), applicationDTO.getName());
- }
- return null;
- }
- @Override
- public ApplicationStatusVO getStatus(String projectName, String name) {
- Deployment deployment = deploymentApi.get(projectName, name);
- if (deployment == null) return null;//抛出异常
- return buildApplicationStatusVO(deployment);
- }
- private Deployment buildDeployment(ApplicationDTO applicationDTO) {
- Deployment deployment = applicationDTO.toDeployment();
- //将registry密钥作为imagePullSecrets注入
- List<String> registrySecrets = secretApi
- .getSecretListByType(
- applicationDTO.getProjectName(),
- SecretTypeEnum.REGISTRY)
- .stream()
- .map(SecretVO::getName)
- .collect(Collectors.toList()
- );
- deployment.setImagePullSecrets(registrySecrets);
- //将一般密钥作为环境变量注入
- List<SecretVO> genericSecrets = secretApi.getSecretListByType(applicationDTO.getProjectName(), SecretTypeEnum.Generic);
- Map<String, String> env = new HashMap<>();
- genericSecrets.forEach(secretVO -> env.putAll(secretVO.getData()));
- deployment.getContainers().forEach(containerDTO -> containerDTO.setEnv(env));
- return deployment;
- }
- private Service buildService(ApplicationDTO applicationDTO) {
- return applicationDTO.toService();
- }
- //@todo 构建Ingress
- //@fixme 潜在bug 如果容器上的IP和Service上的IP并非一一对应,根据容器的IP暴露Service会出现映射错误
- private Ingress buildIngress(ApplicationDTO applicationDTO) {
- String appName = applicationDTO.getName();
- String projectName = applicationDTO.getProjectName();
- Ingress ingress = new Ingress();
- ingress.setName(appName);
- ingress.setNamespace(projectName);
- ingress.setHttpHost("deernowl.cn");
- //@todo lambda表达式解决
- Set<Ingress.IngressDetail> detailDTOS = new HashSet<>();
- for (ContainerDTO containerDTO : applicationDTO.getContainers()) {
- String containerName = containerDTO.getName();
- Set<Ingress.IngressDetail> ingressDetails = containerDTO.getPorts()
- .stream()
- .filter(PortDTO::isExpose)
- .map(portDTO ->{
- Ingress.IngressDetail ingressDetail = new Ingress.IngressDetail();
- ingressDetail.setServiceName(applicationDTO.getName());
- ingressDetail.setPort(portDTO.getPort());
- ingressDetail.setPath("/" + appName + "/" + containerName);
- return ingressDetail;
- })
- .collect(Collectors.toSet());
- detailDTOS.addAll(ingressDetails);
- }
- ingress.setHttpRules(detailDTOS);
- return ingress;
- }
- private ApplicationVO buildApplicationVO(ApplicationDTO applicationDTO, Deployment deployment, Ingress ingress) {
- ApplicationVO applicationVO = new ApplicationVO();
- applicationVO.setName(applicationDTO.getName());
- applicationVO.setProjectName(applicationDTO.getProjectName());
- if (ingress.getHttpRules() != null) {
- applicationVO.setUrl(
- ingress.getHttpRules().stream()
- .map(rule -> ingress.getHttpHost() + rule).collect(Collectors.toList())
- );
- }
- ApplicationStatusVO applicationStatusVO = buildApplicationStatusVO(deployment);
- applicationVO.setStatus(applicationStatusVO);
- return applicationVO;
- }
- private ApplicationStatusVO buildApplicationStatusVO(Deployment deployment) {
- ApplicationStatusVO applicationStatusVO = new ApplicationStatusVO();
- applicationStatusVO.setReadyReplicas(deployment.getStatus().getReadyReplicas());
- applicationStatusVO.setDesiredReplicas(deployment.getReplicas());
- return applicationStatusVO;
- }
- }
|