1
0
Просмотр исходного кода

feat: 部署实例相关实现补完,待改成异步,待gitlab接口

370774330@qq.com 5 лет назад
Родитель
Сommit
2de57c95bc

+ 48 - 0
core/src/main/java/seecoder/devcloud/core/pipeline/inspector/PipelineInspector.java

@@ -0,0 +1,48 @@
+package seecoder.devcloud.core.pipeline.inspector;
+
+import seecoder.devcloud.api.k8s.DeploymentApi;
+import seecoder.devcloud.api.k8s.K8sConstants;
+import seecoder.devcloud.api.k8s.NamespaceApi;
+import seecoder.devcloud.api.k8s.model.DeploymentStatus;
+import seecoder.devcloud.api.k8s.model.Namespace;
+import seecoder.devcloud.common.util.SpringUtil;
+import seecoder.devcloud.core.pipeline.Context;
+
+/**
+ * @author PuHong Weng
+ * @date 2021/3/23
+ * @description:
+ * 每一条流水线与一个部署一对一关联
+ * 用于查看部署状态、删除部署等功能
+ */
+public class PipelineInspector {
+
+    private final Context context;
+
+    private final NamespaceApi namespaceApi;
+
+    private final DeploymentApi deploymentApi;
+
+    public PipelineInspector(Context context) {
+        this.context = context;
+        this.deploymentApi = SpringUtil.getBean(DeploymentApi.class);
+        namespaceApi = SpringUtil.getBean(NamespaceApi.class);
+
+    }
+
+    public DeploymentStatus inspectStatus(){
+        String name = context.getProjectName() + K8sConstants.DEPLOYMENT_SUFFIX;
+        DeploymentStatus status = deploymentApi.getStatus(context.getNamespace(),name);
+        return status;
+    }
+
+
+    public void delete(){
+        //todo 异步
+        Namespace namespace = new Namespace();
+        namespace.setName(context.getNamespace());
+        namespaceApi.delete(namespace);
+    }
+
+
+}

+ 33 - 0
core/src/main/java/seecoder/devcloud/core/pipeline/inspector/PipelineInspectorFactory.java

@@ -0,0 +1,33 @@
+package seecoder.devcloud.core.pipeline.inspector;
+
+import seecoder.devcloud.core.pipeline.Context;
+
+/**
+ * @author PuHong Weng
+ * @date 2021/3/23
+ * @description:
+ */
+public class PipelineInspectorFactory {
+
+
+    /**
+     * 流水线初始化
+     * @param namespace 流水线的k8s namespace,devcloud后端采用{@code Project}中的{@code name}作为namespace
+     * @param projectName 流水线部署k8s的应用名称,devcloud后端采用{@code Pipeline}中的{@code name} 作为project name
+     * @param pipelineId 流水线id
+     * @param templateName 模板名称
+     */
+    public static PipelineInspector init(String namespace, String projectName, Integer pipelineId, String templateName) {
+
+        //初始化context
+        Context context = Context.builder()
+                .projectName(projectName)
+                .namespace(namespace)
+                .pipelineId(pipelineId)
+                .templateName(templateName)
+                .build();
+
+        return new PipelineInspector(context);
+    }
+
+}

+ 5 - 3
web/src/main/java/seecoder/devcloud/web/model/vo/pipeline/DeploymentInfoVO.java

@@ -2,6 +2,7 @@ package seecoder.devcloud.web.model.vo.pipeline;
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Builder;
 import lombok.Data;
 
 import java.sql.Timestamp;
@@ -10,14 +11,15 @@ import java.sql.Timestamp;
  * @author PuHong Weng
  * @date 2021/3/11
  * @description:
+ * 部署的实例的字段其实来自于pipeline和pipeline history
+ * status字段也需要去取
+ * 所以目前没有为部署实例编写持久化PO
  */
 @Data
+@Builder
 @ApiModel("流水线部署的实例信息")
 public class DeploymentInfoVO {
 
-    @ApiModelProperty("实例id")
-    private Integer id;
-
     @ApiModelProperty("关联的流水线")
     private Integer pipelineId;
 

+ 53 - 7
web/src/main/java/seecoder/devcloud/web/service/impl/pipeline/DeploymentServiceImpl.java

@@ -2,17 +2,26 @@ package seecoder.devcloud.web.service.impl.pipeline;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import seecoder.devcloud.api.ApplicationProperties;
+import seecoder.devcloud.api.k8s.model.DeploymentStatus;
+import seecoder.devcloud.common.exceptions.AccessDeniedException;
 import seecoder.devcloud.core.pipeline.Pipeline;
 import seecoder.devcloud.core.pipeline.PipelineException;
 import seecoder.devcloud.core.pipeline.PipelineFactory;
+import seecoder.devcloud.core.pipeline.inspector.PipelineInspector;
+import seecoder.devcloud.core.pipeline.inspector.PipelineInspectorFactory;
+import seecoder.devcloud.web.dao.pipeline.PipelineHistoryMapper;
 import seecoder.devcloud.web.dao.pipeline.PipelineMapper;
 import seecoder.devcloud.web.dao.project.ProjectMapper;
+import seecoder.devcloud.web.model.po.pipeline.PipelineHistoryPO;
 import seecoder.devcloud.web.model.po.pipeline.PipelinePO;
 import seecoder.devcloud.web.model.po.project.ProjectPO;
 import seecoder.devcloud.web.model.vo.pipeline.DeploymentInfoVO;
 import seecoder.devcloud.web.service.pipeline.DeploymentService;
 
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * @author PuHong Weng
@@ -24,24 +33,57 @@ public class DeploymentServiceImpl implements DeploymentService {
 
     private final PipelineMapper pipelineMapper;
 
+    private final PipelineHistoryMapper pipelineHistoryMapper;
+
     private final ProjectMapper projectMapper;
 
+    private final ApplicationProperties properties;
+
 
     @Autowired
-    public DeploymentServiceImpl(PipelineMapper pipelineMapper, ProjectMapper projectMapper) {
+    public DeploymentServiceImpl(PipelineMapper pipelineMapper, PipelineHistoryMapper pipelineHistoryMapper, ProjectMapper projectMapper, ApplicationProperties properties) {
         this.pipelineMapper = pipelineMapper;
+        this.pipelineHistoryMapper = pipelineHistoryMapper;
         this.projectMapper = projectMapper;
+        this.properties = properties;
     }
 
 
     @Override
-    public List<DeploymentInfoVO> retrieveDeploymentInfos(Integer projectId) {
-        //todo  需要远端查看k8s实例的status
-        return null;
+    public List<DeploymentInfoVO> retrieveDeploymentInfos(Integer projectId) throws AccessDeniedException {
+        //projectAuthentication(projectId);
+        ProjectPO project = projectMapper.getProjectById(projectId);
+        List<PipelinePO> pipelines = pipelineMapper.selectByProjectId(projectId);
+        // 获取项目所关联的所有流水线
+        List<Integer> pipelineIds = pipelines.stream().map(PipelinePO::getId).collect(Collectors.toList());
+        // 获取流水线历史
+        List<PipelineHistoryPO> histories = pipelineHistoryMapper.selectRecentlyHistoryBy(pipelineIds);
+        Map<Integer, PipelineHistoryPO> historyMap = histories.stream().collect(Collectors.toMap(PipelineHistoryPO::getPipelineId, x->x));
+        return pipelines.stream().map(x->{
+            String accessUrl = x.getName()+"."+project.getName()+ properties.getK8s().getIngressHostSuffix();
+            PipelineHistoryPO history = historyMap.get(x.getId());
+            PipelineInspector inspector = PipelineInspectorFactory.init(project.getName(),x.getName(),x.getId(),x.getTemplateName());
+            //获取状态
+            String status = null;
+            DeploymentStatus deploymentStatus = inspector.inspectStatus();
+            if(deploymentStatus.isAvailable()){
+                status = "正常运行";
+            } else{
+                status = "不可用: " + deploymentStatus.getProgressingMessage();
+            }
+            return DeploymentInfoVO.builder()
+                    .pipelineId(x.getId())
+                    .name(x.getName())
+                    .deployedTime(history.getStartTime())
+                    .accessUrl(accessUrl)
+                    .status(status)
+                    .build();
+        }).collect(Collectors.toList());
     }
 
     @Override
-    public void deploy(Integer projectId, Integer pipelineId) {
+    public void deploy(Integer projectId, Integer pipelineId) throws AccessDeniedException {
+        //projectAuthentication(projectId);
         PipelinePO pipelinePO = pipelineMapper.selectById(pipelineId);
         ProjectPO projectPO = projectMapper.getProjectById(projectId);
         try {
@@ -55,7 +97,11 @@ public class DeploymentServiceImpl implements DeploymentService {
     }
 
     @Override
-    public void delete(Integer projectId, Integer pipelineId) {
-
+    public void delete(Integer projectId, Integer pipelineId) throws AccessDeniedException {
+        //projectAuthentication(projectId);
+        ProjectPO project = projectMapper.getProjectById(projectId);
+        PipelinePO pipelinePO = pipelineMapper.selectById(pipelineId);
+        PipelineInspector inspector = PipelineInspectorFactory.init(project.getName(),pipelinePO.getName(),pipelineId,pipelinePO.getTemplateName());
+        inspector.delete();
     }
 }

+ 8 - 20
web/src/main/java/seecoder/devcloud/web/service/impl/pipeline/PipelineServiceImpl.java

@@ -10,16 +10,14 @@ import seecoder.devcloud.web.dao.pipeline.PipelineHistoryMapper;
 import seecoder.devcloud.web.dao.pipeline.PipelineMapper;
 import seecoder.devcloud.web.dao.project.ProjectMapper;
 import seecoder.devcloud.web.dao.user.UserMapper;
-import seecoder.devcloud.web.model.po.pipeline.PipelinePO;
 import seecoder.devcloud.web.model.po.pipeline.PipelineHistoryPO;
-import seecoder.devcloud.web.model.po.project.ProjectPO;
+import seecoder.devcloud.web.model.po.pipeline.PipelinePO;
 import seecoder.devcloud.web.model.po.user.UserPO;
 import seecoder.devcloud.web.model.vo.pipeline.PipelineConfigVO;
 import seecoder.devcloud.web.model.vo.pipeline.PipelineCreateVO;
 import seecoder.devcloud.web.model.vo.pipeline.PipelineHistoryVO;
 import seecoder.devcloud.web.model.vo.pipeline.PipelineInfoVO;
 import seecoder.devcloud.web.service.pipeline.PipelineService;
-import seecoder.devcloud.web.service.user.UserService;
 
 import java.util.List;
 import java.util.Map;
@@ -53,7 +51,7 @@ public class PipelineServiceImpl implements PipelineService {
 
     @Override
     public List<PipelineInfoVO> retrievePipelineInfos(Integer projectId) throws AccessDeniedException {
-        projectAuthentication(projectId);
+        //projectAuthentication(projectId);
         // 获取项目所关联的所有流水线
         List<PipelinePO> pipelinePOS = pipelineMapper.selectByProjectId(projectId);
         List<Integer> pipelineIds = pipelinePOS.stream().map(PipelinePO::getId).collect(Collectors.toList());
@@ -68,13 +66,13 @@ public class PipelineServiceImpl implements PipelineService {
 
     @Override
     public PipelineConfigVO retrievePipelineConfig(Integer projectId, Integer pipelineId) throws AccessDeniedException {
-        projectAuthentication(projectId);
+        //projectAuthentication(projectId);
         return new PipelineConfigVO(pipelineMapper.selectById(pipelineId));
     }
 
     @Override
     public List<PipelineHistoryVO> retrievePipelineHistory(Integer projectId, Integer pipelineId) throws AccessDeniedException {
-        projectAuthentication(projectId);
+        //projectAuthentication(projectId);
         List<PipelineHistoryPO> histories = pipelineHistoryMapper.selectByPipelineId(pipelineId);
         List<Integer> userIds = histories.stream().map(PipelineHistoryPO::getUserId).collect(Collectors.toList());
         Map<Integer, String> usernameMap =  userMapper.selectByIds(userIds).stream().collect(Collectors.toMap(UserPO::getId, UserPO::getUsername));
@@ -83,7 +81,7 @@ public class PipelineServiceImpl implements PipelineService {
 
     @Override
     public void createPipelineConfig(PipelineCreateVO pipelineCreateVO) throws ServiceException {
-        projectAuthentication(pipelineCreateVO.getProjectId());
+        //projectAuthentication(pipelineCreateVO.getProjectId());
         PipelinePO pipeline = null;
         try {
             pipeline = PipelinePO.builder()
@@ -102,14 +100,14 @@ public class PipelineServiceImpl implements PipelineService {
 
     @Override
     public void savePipelineConfig(Integer projectId, Integer pipelineId, String configJson) throws AccessDeniedException {
-        projectAuthentication(projectId);
+        //projectAuthentication(projectId);
         pipelineMapper.updateConfigJson(pipelineId,configJson);
 
     }
 
     @Override
     public void deletePipelineConfig(Integer projectId, Integer pipelineId) throws AccessDeniedException {
-        projectAuthentication(projectId);
+        //projectAuthentication(projectId);
         pipelineMapper.delete(pipelineId);
         //todo 部署要不要删
     }
@@ -119,17 +117,7 @@ public class PipelineServiceImpl implements PipelineService {
         return PipelineTemplateTable.getTemplateNames();
     }
 
-    /**
-     * 判断用户是否有权限修改这些流水线配置,
-     * 防止用户修改提交的参数从而修改其他组的流水线
-     */
-    private void projectAuthentication(Integer projectId) throws AccessDeniedException {
-        UserPO userPO = UserService.loginUser();
-        List<ProjectPO> projectPOS = projectMapper.listProjectsByUserId(userPO.getId());
-        if (projectPOS.stream().noneMatch(project -> project.getId()==projectId)){
-            throw new AccessDeniedException("您没有操作此项目的权限");
-        }
-    }
+
 
 
 

+ 2 - 5
web/src/main/java/seecoder/devcloud/web/service/impl/project/ProjectServiceImpl.java

@@ -51,7 +51,6 @@ public class ProjectServiceImpl implements ProjectService {
     public ProjectVO createProject(ProjectCreateVO vo) throws ServiceException {
         ProjectPO po = new ProjectPO();
         BeanUtils.copyProperties(vo,po);
-
         try {
             //todo 创建完项目还要设置url
             int projectId = seecoderGitlabApi.createProject(po.getName(), VisibilityForm.PRIVATE);
@@ -60,9 +59,6 @@ public class ProjectServiceImpl implements ProjectService {
             throw new ServiceException("创建项目时发生异常[project id:"+po.getId()+", " + e.getMessage() + "]", e);
         }
         projectMapper.insertProject(po);
-
-
-        // TODO:在对应的gitlab仓库中注册WEBHOOK
         try {
             seecoderGitlabApi.addWebHook(po.getId(), properties.getGitlab().getWebhookProxy(), true,false,false);
         } catch (SeecoderGitlabException e) {
@@ -74,11 +70,12 @@ public class ProjectServiceImpl implements ProjectService {
 
     @Override
     public void addMember(Integer projectId, Integer userId) {
+        //todo gitlab项目加权限
 
     }
 
     @Override
     public void deleteProject(int projectId) {
-        //TODO:不知道该怎么做,懒删除?还是直接删?
+        //TODO:不知道该怎么做,懒删除?还是直接删? 暂时不提供
     }
 }

+ 4 - 3
web/src/main/java/seecoder/devcloud/web/service/pipeline/DeploymentService.java

@@ -1,5 +1,6 @@
 package seecoder.devcloud.web.service.pipeline;
 
+import seecoder.devcloud.common.exceptions.AccessDeniedException;
 import seecoder.devcloud.web.model.vo.pipeline.DeploymentInfoVO;
 
 import java.util.List;
@@ -14,18 +15,18 @@ public interface DeploymentService {
     /**
      * 获取项目部署的实例信息
      */
-    List<DeploymentInfoVO> retrieveDeploymentInfos(Integer projectId);
+    List<DeploymentInfoVO> retrieveDeploymentInfos(Integer projectId) throws AccessDeniedException;
 
 
     /**
      * 执行一条pipepine
      * todo 异步/异步异常捕获刷新result
      */
-    void deploy(Integer projectId,Integer pipelineId);
+    void deploy(Integer projectId,Integer pipelineId) throws AccessDeniedException;
 
     /**
      * 删除一个实例
      * todo 异步/异步异常捕获刷新result
      */
-    void delete(Integer projectId,Integer pipelineId);
+    void delete(Integer projectId,Integer pipelineId) throws AccessDeniedException;
 }

+ 21 - 0
web/src/main/java/seecoder/devcloud/web/service/user/UserService.java

@@ -2,11 +2,17 @@ package seecoder.devcloud.web.service.user;
 
 
 import org.springframework.security.core.context.SecurityContextHolder;
+import seecoder.devcloud.common.exceptions.AccessDeniedException;
 import seecoder.devcloud.common.exceptions.ServiceException;
+import seecoder.devcloud.common.util.SpringUtil;
+import seecoder.devcloud.web.dao.project.ProjectMapper;
+import seecoder.devcloud.web.model.po.project.ProjectPO;
 import seecoder.devcloud.web.model.po.user.UserPO;
 import seecoder.devcloud.web.model.vo.user.GitlabUserCreateVO;
 import seecoder.devcloud.web.model.vo.user.UserVO;
 
+import java.util.List;
+
 public interface UserService {
 
     UserVO createGitlabUser(GitlabUserCreateVO vo) throws ServiceException;
@@ -20,4 +26,19 @@ public interface UserService {
     static UserPO loginUser(){
         return (UserPO) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
     }
+
+    /**
+     * 判断用户是否有权限修改这些流水线配置,用户必须所属这谢谢项目,才具有权限
+     * 防止用户修改提交的参数从而修改其他组的流水线
+     * todo 所有涉及项目、用户的功能都必须查看此用户有无此项目的权限
+     *  但是gitlab那边接口没测所以没有办法
+     */
+    static void projectAuthentication(Integer projectId) throws AccessDeniedException {
+        UserPO userPO = UserService.loginUser();
+        //todo gitlab获取
+        List<ProjectPO> projectPOS = SpringUtil.getBean(ProjectMapper.class).listProjectsByUserId(userPO.getId());
+        if (projectPOS.stream().noneMatch(project -> project.getId()==projectId)){
+            throw new AccessDeniedException("您没有操作此项目的权限");
+        }
+    }
 }