Explorar o código

style: 更改k8s更新/创建判断

370774330@qq.com %!s(int64=5) %!d(string=hai) anos
pai
achega
6fd23282ee

+ 4 - 0
core/src/main/java/seecoder/devcloud/core/pipeline/Context.java

@@ -43,6 +43,10 @@ public class Context {
     @Builder.Default
     private String result = "";
 
+    public void appendResult(String msg){
+        result = result + msg;
+    }
+
     public void appendSuccessResult(String msg){
         result = result + "Success: " + msg + "\n";
     }

+ 3 - 35
core/src/main/java/seecoder/devcloud/core/pipeline/handler/JavaImageBuildHandler.java

@@ -75,39 +75,7 @@ public class JavaImageBuildHandler extends AbstractHandler {
             throw new PipelineException(HttpStatus.SC_SERVICE_UNAVAILABLE,PipelineException.DOCKERFILE_CREATE_ERROR,e);
         }
 
-//        //3. 读取项目 groupId artifactId version, 替换dockerfile的project name
-//        //todo 因为不知道学生构建的jar名,且dockerapi没有提供可以输入ARG参数的接口,逼不得已只能读取pom来获取jar包名。
-//        // 这种默认的实现形式,必须保证需要运行的项目pom在根目录(单模块)
-//        // pom的结构顺序没有经过人为调整,不奇葩(也就是groupId artifactId version按默认就在pom最前面)
-//        // 使用xml 解析强行读取
-//        // 待使用更好的实现
-//        String artifactId = null;
-//        String version = null;
-//        File pom = Paths.get(directory.toString(),"pom.xml").toFile();
-//        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
-//        DocumentBuilder dBuilder;
-//        Document doc = null;
-//        String jarName = context.getConfigs().getOrDefault("jarName",null);
-//        if (jarName == null){
-//            try {
-//                dBuilder = dbFactory.newDocumentBuilder();
-//                doc = dBuilder.parse(pom);
-//                NodeList nodes = doc.getChildNodes().item(0).getChildNodes();
-//                //按默认顺序 前二十个xml节点肯定有那三个量了
-//                for (int i = 0; i < 20; i++){
-//                    if ("artifactId".equals(nodes.item(i).getNodeName())) {
-//                        artifactId = nodes.item(i).getTextContent();
-//                    } else if ("version".equals(nodes.item(i).getNodeName())){
-//                        version = nodes.item(i).getTextContent();
-//                    }
-//                }
-//            } catch (Exception e) {
-//                throw new PipelineException(HttpStatus.SC_SERVICE_UNAVAILABLE,PipelineException.POM_READ_ERROR,e);
-//            }
-//            jarName = artifactId+"-"+version;
-//        }
-
-        //4. 修改dockerfile内部需要替换的内容
+        //3. 修改dockerfile内部需要替换的内容
         List<String> dockerfileLines = null;
         try {
             dockerfileLines = Files.readAllLines(dockerfile);
@@ -120,7 +88,7 @@ public class JavaImageBuildHandler extends AbstractHandler {
         } catch (IOException e) {
             throw new PipelineException(HttpStatus.SC_SERVICE_UNAVAILABLE,PipelineException.DOCKERFILE_MODIFY_ERROR,e);
         }
-        //5. 镜像构建
+        //4. 镜像构建
         String imageTag = String.valueOf(new Date().getTime());
         StringBuilder sb = new StringBuilder();
         final int DEFAULT_BUFFER_LENGTH = 200;
@@ -151,7 +119,7 @@ public class JavaImageBuildHandler extends AbstractHandler {
                 context.setResult(context.getResult() + "IMAGE BUILD DETAILS:" + sb.toString());
                 throw new PipelineException(HttpStatus.SC_SERVICE_UNAVAILABLE, PipelineException.IMAGE_BUILD_ERROR ,e);
             }
-        //6. 将镜像名字加入context
+        //5. 将镜像名字加入context
         context.getConfigs().put("imageName", imageName);
         context.getConfigs().put("imageTag", imageTag);
         context.appendSuccessResult("镜像构建成功,已推送进仓库");

+ 18 - 13
core/src/main/java/seecoder/devcloud/core/pipeline/handler/K8sDeploymentHandler.java

@@ -10,12 +10,14 @@ import seecoder.devcloud.api.k8s.exception.K8sApiException;
 import seecoder.devcloud.api.k8s.model.Container;
 import seecoder.devcloud.api.k8s.model.ContainerPort;
 import seecoder.devcloud.api.k8s.model.Deployment;
+import seecoder.devcloud.api.k8s.model.K8sObjectRequest;
 import seecoder.devcloud.api.k8s.vo.SecretVO;
 import seecoder.devcloud.common.util.SpringUtil;
 import seecoder.devcloud.core.pipeline.Context;
 import seecoder.devcloud.core.pipeline.PipelineException;
 
 import java.util.Collections;
+import java.util.List;
 
 /**
  * @author PuHong Weng
@@ -67,7 +69,7 @@ public class K8sDeploymentHandler extends AbstractHandler {
 
         //2. 配置容器
         Container container = Container.builder()
-                .image(applicationProperties.getDocker().getRegistry()+"/"+imageName+":"+imageTag)
+                .image(applicationProperties.getDocker().getRegistry() + "/" + imageName + ":" + imageTag)
                 .name(deployName + K8sConstants.CONTAINER_SUFFIX)
                 .ports(Collections.singleton(containerPort))
                 .build();
@@ -99,25 +101,28 @@ public class K8sDeploymentHandler extends AbstractHandler {
         deployment.setImagePullSecrets(Collections.singletonList(DEFAULT_IMAGE_PULL_SECRET_NAME));
 
 
-
-
         //4. 创建Deployment。
         try {
-            deploymentApi.create(deployment);
-            log.info("deployment创建成功: [namespace: " + context.getNamespace() +", deployName: " + context.getTemplateName() + "]");
-        } catch (K8sApiException e){
-            if (e.getCode() == K8sApiException.ALREADY_EXIST){
-                deploymentApi.update(deployment);
-                log.info("deployment更新成功: [namespace: " + context.getNamespace() +", deployName: " + context.getTemplateName() + "]");
+            List<Deployment> deployments = deploymentApi.getByCondition(K8sObjectRequest.builder()
+                    .namespace(context.getNamespace())
+                    .name(context.getDeployName() + K8sConstants.DEPLOYMENT_SUFFIX)
+                    .build());
+            if (deployments.size() == 0) {
+                deploymentApi.create(deployment);
+                log.info("deployment创建成功: [namespace: " + context.getNamespace() + ", deployName: " + context.getTemplateName() + "]");
             } else {
-                context.appendErrorResult(PipelineException.DEPLOYMENT_CREATE_ERROR,e);
-                throw new PipelineException(HttpStatus.SC_SERVICE_UNAVAILABLE,PipelineException.DEPLOYMENT_CREATE_ERROR,e);
+                deploymentApi.update(deployment);
+                log.info("deployment更新成功: [namespace: " + context.getNamespace() + ", deployName: " + context.getTemplateName() + "]");
+
             }
+        } catch (K8sApiException e) {
+            context.appendErrorResult(PipelineException.DEPLOYMENT_CREATE_ERROR, e);
+            throw new PipelineException(HttpStatus.SC_SERVICE_UNAVAILABLE, PipelineException.DEPLOYMENT_CREATE_ERROR, e);
         }
 
         //5. 存入暴露的端口
-        context.getConfigs().put("port",String.valueOf(port));
-        context.appendSuccessResult("K8s Deployment部署成功: [namespace: " + context.getNamespace() +", deployName: " + context.getTemplateName() + "]");
+        context.getConfigs().put("port", String.valueOf(port));
+        context.appendSuccessResult("K8s Deployment部署成功: [namespace: " + context.getNamespace() + ", deployName: " + context.getTemplateName() + "]");
     }
 
 }

+ 13 - 7
core/src/main/java/seecoder/devcloud/core/pipeline/handler/K8sIngressHandler.java

@@ -7,11 +7,13 @@ import seecoder.devcloud.api.k8s.IngressApi;
 import seecoder.devcloud.api.k8s.K8sConstants;
 import seecoder.devcloud.api.k8s.exception.K8sApiException;
 import seecoder.devcloud.api.k8s.model.Ingress;
+import seecoder.devcloud.api.k8s.model.K8sObjectRequest;
 import seecoder.devcloud.common.util.SpringUtil;
 import seecoder.devcloud.core.pipeline.Context;
 import seecoder.devcloud.core.pipeline.PipelineException;
 
 import java.util.Collections;
+import java.util.List;
 
 /**
  * @author PuHong Weng
@@ -64,16 +66,20 @@ public class K8sIngressHandler extends AbstractHandler {
 
         //3. 创建
         try {
-            ingressApi.create(ingress);
-            log.info("ingress创建成功");
-        } catch (K8sApiException e){
-            if (e.getCode() == K8sApiException.ALREADY_EXIST){
+            List<Ingress> ingresses = ingressApi.getByCondition(K8sObjectRequest.builder()
+                    .namespace(context.getNamespace())
+                    .name(context.getDeployName() + K8sConstants.INGRESS_SUFFIX)
+                    .build());
+            if (ingresses.size()==0){
+                ingressApi.create(ingress);
+                log.info("ingress创建成功");
+            } else{
                 ingressApi.update(ingress);
                 log.info("ingress更新成功");
-            } else {
-                context.appendErrorResult(PipelineException.INGRESS_CREATE_ERROR,e);
-                throw new PipelineException(HttpStatus.SC_SERVICE_UNAVAILABLE,PipelineException.INGRESS_CREATE_ERROR,e);
             }
+        } catch (K8sApiException e){
+            context.appendErrorResult(PipelineException.INGRESS_CREATE_ERROR,e);
+            throw new PipelineException(HttpStatus.SC_SERVICE_UNAVAILABLE,PipelineException.INGRESS_CREATE_ERROR,e);
         }
 
         //4. 存入访问路径

+ 14 - 10
core/src/main/java/seecoder/devcloud/core/pipeline/handler/K8sNamespaceHandler.java

@@ -5,11 +5,14 @@ import org.apache.http.HttpStatus;
 import seecoder.devcloud.api.k8s.NamespaceApi;
 import seecoder.devcloud.api.k8s.SecretApi;
 import seecoder.devcloud.api.k8s.exception.K8sApiException;
+import seecoder.devcloud.api.k8s.model.K8sObjectRequest;
 import seecoder.devcloud.api.k8s.model.Namespace;
 import seecoder.devcloud.common.util.SpringUtil;
 import seecoder.devcloud.core.pipeline.Context;
 import seecoder.devcloud.core.pipeline.PipelineException;
 
+import java.util.List;
+
 /**
  * @author PuHong Weng
  * @date 2021/2/2
@@ -34,17 +37,18 @@ public class K8sNamespaceHandler extends AbstractHandler {
 
         //todo namespace在底下资源未删除时,不能轻易删除重建,只能直接通过异常查是否已创建,丑陋,待修改
         try {
-            namespace = namespaceApi.create(namespace);
-            log.info("Namespace创建成功: [namespace: " + context.getNamespace() +", deployName: " + context.getTemplateName() + "]");
-        } catch (K8sApiException e){
-            if (e.getCode() == K8sApiException.ALREADY_EXIST){
-                log.info("Namespace已经存在, 无需新建: [namespace: " + context.getNamespace() +", deployName: " + context.getTemplateName() + "]");
-            } else{
-                context.appendErrorResult(PipelineException.NAMESPACE_CREATE_ERROR,e);
-                throw new PipelineException(HttpStatus.SC_SERVICE_UNAVAILABLE,PipelineException.NAMESPACE_CREATE_ERROR,e);
+            List<Namespace> namespaces = namespaceApi.getByCondition(K8sObjectRequest.builder()
+                    .name(context.getNamespace()).build());
+            if (namespaces.size() == 0) {
+                namespace = namespaceApi.create(namespace);
+                log.info("Namespace创建成功: [namespace: " + context.getNamespace() + ", deployName: " + context.getTemplateName() + "]");
+            } else {
+                log.info("Namespace已经存在, 无需新建: [namespace: " + context.getNamespace() + ", deployName: " + context.getTemplateName() + "]");
             }
+        } catch (K8sApiException e) {
+            context.appendErrorResult(PipelineException.NAMESPACE_CREATE_ERROR, e);
+            throw new PipelineException(HttpStatus.SC_SERVICE_UNAVAILABLE, PipelineException.NAMESPACE_CREATE_ERROR, e);
         }
-
-        context.appendSuccessResult("K8s Namespace创建成功: [namespace: " + context.getNamespace() +", deployName: " + context.getTemplateName() + "]");
+        context.appendSuccessResult("K8s Namespace创建成功: [namespace: " + context.getNamespace() + ", deployName: " + context.getTemplateName() + "]");
     }
 }

+ 16 - 10
core/src/main/java/seecoder/devcloud/core/pipeline/handler/K8sServiceHandler.java

@@ -5,6 +5,7 @@ import org.apache.http.HttpStatus;
 import seecoder.devcloud.api.k8s.K8sConstants;
 import seecoder.devcloud.api.k8s.ServiceApi;
 import seecoder.devcloud.api.k8s.exception.K8sApiException;
+import seecoder.devcloud.api.k8s.model.K8sObjectRequest;
 import seecoder.devcloud.api.k8s.model.Service;
 import seecoder.devcloud.api.k8s.model.ServicePort;
 import seecoder.devcloud.common.util.SpringUtil;
@@ -12,6 +13,7 @@ import seecoder.devcloud.core.pipeline.Context;
 import seecoder.devcloud.core.pipeline.PipelineException;
 
 import java.util.Collections;
+import java.util.List;
 
 /**
  * @author PuHong Weng
@@ -41,7 +43,7 @@ public class K8sServiceHandler extends AbstractHandler {
         //1. 配置K8s的service
         Service service = new Service();
         service.setNamespace(context.getNamespace());
-        service.setName(context.getDeployName()+ K8sConstants.SERVICE_SUFFIX);
+        service.setName(context.getDeployName() + K8sConstants.SERVICE_SUFFIX);
         //标签选择器选择 此项目对应的deployment的name
         service.setSelectors(Collections.singletonMap(K8sConstants.APPLICATION_LABEL, context.getDeployName()));
         service.setServicePorts(
@@ -50,20 +52,24 @@ public class K8sServiceHandler extends AbstractHandler {
 
         //2. 创建
         try {
-            serviceApi.create(service);
-            log.info("service创建成功: [namespace: " + context.getNamespace() +", deployName: " + context.getTemplateName() + "]");
-        } catch (K8sApiException e){
-            if (e.getCode() == K8sApiException.ALREADY_EXIST){
-                serviceApi.update(service);
-                log.info("service更新成功: [namespace: " + context.getNamespace() +", deployName: " + context.getTemplateName() + "]");
+            List<Service> services = serviceApi.getByCondition(K8sObjectRequest.builder()
+                    .namespace(context.getNamespace())
+                    .name(context.getDeployName() + K8sConstants.SERVICE_SUFFIX)
+                    .build());
+            if (services.size() == 0) {
+                serviceApi.create(service);
+                log.info("service创建成功: [namespace: " + context.getNamespace() + ", deployName: " + context.getTemplateName() + "]");
             } else {
-                context.appendErrorResult(PipelineException.SERVICE_CREATE_ERROR,e);
-                throw new PipelineException(HttpStatus.SC_SERVICE_UNAVAILABLE,PipelineException.SERVICE_CREATE_ERROR,e);
+                serviceApi.update(service);
+                log.info("service更新成功: [namespace: " + context.getNamespace() + ", deployName: " + context.getTemplateName() + "]");
             }
+        } catch (K8sApiException e) {
+            context.appendErrorResult(PipelineException.SERVICE_CREATE_ERROR, e);
+            throw new PipelineException(HttpStatus.SC_SERVICE_UNAVAILABLE, PipelineException.SERVICE_CREATE_ERROR, e);
         }
 
         //3. 存放暴露的端口
         context.getConfigs().put("servicePort", String.valueOf(servicePort));
-        context.appendSuccessResult("K8s Service创建成功: [namespace: " + context.getNamespace() +", deployName: " + context.getTemplateName() + "]");
+        context.appendSuccessResult("K8s Service创建成功: [namespace: " + context.getNamespace() + ", deployName: " + context.getTemplateName() + "]");
     }
 }

+ 4 - 0
core/src/main/java/seecoder/devcloud/core/pipeline/handler/NodeImageBuildHandler.java

@@ -4,6 +4,7 @@ import com.spotify.docker.client.ProgressHandler;
 import com.spotify.docker.client.exceptions.DockerException;
 import com.spotify.docker.client.messages.ProgressMessage;
 import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.StringUtils;
 import org.apache.http.HttpStatus;
 import org.eclipse.jgit.api.Git;
@@ -27,6 +28,7 @@ import java.util.Date;
  * 前端镜像构建
  */
 @Data
+@Slf4j
 public class NodeImageBuildHandler extends AbstractHandler{
     public final DockerApi dockerApi;
 
@@ -60,6 +62,8 @@ public class NodeImageBuildHandler extends AbstractHandler{
             context.appendErrorResult(PipelineException.GIT_CLONE_ERROR,e);
             throw new PipelineException(HttpStatus.SC_SERVICE_UNAVAILABLE, PipelineException.GIT_CLONE_ERROR,e);
         }
+
+
         //2. 帮助学生创建dockerfile和nginx配置
         Path dockerfile = Paths.get(directory.toString(), "Dockerfile");
         try {