diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..3d16134 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,14 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +/vcs.xml +/compiler.xml +/encodings.xml +/jarRepositories.xml +/misc.xml +/uiDesigner.xml diff --git a/README.md b/README.md new file mode 100644 index 0000000..c4410ba --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# 启动参数 +```` +-DNACOS_CONFIG_SERVER=192.168.105.1:8848 +-DTENANT_CODE=longi +-DDEPLOY_ENV=deploy-ease-dev +-DNACOS_USER=nacos +-DNACOS_PWD=nacos +```` \ No newline at end of file diff --git a/deploy-ease-api/pom.xml b/deploy-ease-api/pom.xml new file mode 100644 index 0000000..057e9cc --- /dev/null +++ b/deploy-ease-api/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + deploy-ease-api + + + + org.springframework.boot + spring-boot-starter-web + + + org.projectlombok + lombok + provided + + + + + + com.qc.soft + deploy-ease + 1.0-SNAPSHOT + + + \ No newline at end of file diff --git a/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/IDictionaryController.java b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/IDictionaryController.java new file mode 100644 index 0000000..506509f --- /dev/null +++ b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/IDictionaryController.java @@ -0,0 +1,21 @@ +package com.qc.soft.deploy.ease.api.controller; + +import com.qc.soft.deploy.ease.api.response.DictionaryResponse; +import com.qc.soft.deploy.ease.api.response.TenantDictionaryResponse; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("/deploy-ease/dict") +public interface IDictionaryController { + + @GetMapping("/system") + List systemDicts(); + + @GetMapping("/tenant") + List tenantDicts(); + +} diff --git a/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/IJenkinsController.java b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/IJenkinsController.java new file mode 100644 index 0000000..a78dcff --- /dev/null +++ b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/IJenkinsController.java @@ -0,0 +1,11 @@ +package com.qc.soft.deploy.ease.api.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/deploy-ease/jenkins") +public interface IJenkinsController { + +} diff --git a/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/IK8sController.java b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/IK8sController.java new file mode 100644 index 0000000..a52eb80 --- /dev/null +++ b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/IK8sController.java @@ -0,0 +1,30 @@ +package com.qc.soft.deploy.ease.api.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +@RestController +@RequestMapping("/deploy-ease/k8s") +public interface IK8sController { + + +// @GetMapping("namespaces") +// List namespaces(); +// +// @GetMapping("deployments/{namespace}") +// List deployments(@PathVariable String namespace); +// +// @GetMapping("/pods/{namespace}/{deploymentName}") +// List pods(@PathVariable String namespace, @PathVariable String deploymentName); +// +// @GetMapping("/pods/{namespace}") +// List pods(@PathVariable String namespace) ; +// +// @GetMapping(value = "/pod/log/{namespace}/{podName}", produces = "text/plain;charset=UTF-8") +// String getPodLog(@PathVariable String namespace, @PathVariable String podName); +// +// +// @GetMapping("/kube/config") +// String getKubeConfig() ; +} diff --git a/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/INacosController.java b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/INacosController.java new file mode 100644 index 0000000..29fc884 --- /dev/null +++ b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/INacosController.java @@ -0,0 +1,9 @@ +package com.qc.soft.deploy.ease.api.controller; + + + +public interface INacosController { + + void instances(); + +} diff --git a/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/IProjectController.java b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/IProjectController.java new file mode 100644 index 0000000..9e2ccf1 --- /dev/null +++ b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/IProjectController.java @@ -0,0 +1,18 @@ +package com.qc.soft.deploy.ease.api.controller; + +import com.qc.soft.deploy.ease.api.response.ProjectResponse; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("/deploy-ease/project") +public interface IProjectController { + + + @GetMapping("/list") + List list(); + +} diff --git a/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/ITestController.java b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/ITestController.java new file mode 100644 index 0000000..c7db786 --- /dev/null +++ b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/ITestController.java @@ -0,0 +1,14 @@ +package com.qc.soft.deploy.ease.api.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/deploy-ease/test") +public interface ITestController { + + @GetMapping("test") + void test(); + +} diff --git a/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/IUserController.java b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/IUserController.java new file mode 100644 index 0000000..1272c70 --- /dev/null +++ b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/controller/IUserController.java @@ -0,0 +1,15 @@ +package com.qc.soft.deploy.ease.api.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/deploy-ease/user") +public interface IUserController { + + + @GetMapping("/login") + boolean login(String userName, String password); + +} diff --git a/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/response/DictionaryResponse.java b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/response/DictionaryResponse.java new file mode 100644 index 0000000..faaae69 --- /dev/null +++ b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/response/DictionaryResponse.java @@ -0,0 +1,21 @@ +package com.qc.soft.deploy.ease.api.response; + + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class DictionaryResponse implements Serializable { + + private String code; + + private String name; + + private String value; + + private boolean status; + + private boolean tenantSharing; + +} \ No newline at end of file diff --git a/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/response/ProjectResponse.java b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/response/ProjectResponse.java new file mode 100644 index 0000000..5d18902 --- /dev/null +++ b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/response/ProjectResponse.java @@ -0,0 +1,16 @@ +package com.qc.soft.deploy.ease.api.response; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class ProjectResponse implements Serializable { + + private String projectCode; + + private String projectName; + + private String tenantCode; + +} \ No newline at end of file diff --git a/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/response/TenantDictionaryResponse.java b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/response/TenantDictionaryResponse.java new file mode 100644 index 0000000..9192d01 --- /dev/null +++ b/deploy-ease-api/src/main/java/com/qc/soft/deploy/ease/api/response/TenantDictionaryResponse.java @@ -0,0 +1,18 @@ +package com.qc.soft.deploy.ease.api.response; + +import lombok.Data; + +@Data +public class TenantDictionaryResponse { + + private String code; + + private String name; + + private String value; + + private boolean status; + + private String tenantCode; + +} \ No newline at end of file diff --git a/deploy-ease-core/pom.xml b/deploy-ease-core/pom.xml new file mode 100644 index 0000000..67283f4 --- /dev/null +++ b/deploy-ease-core/pom.xml @@ -0,0 +1,152 @@ + + + 4.0.0 + deploy-ease-core + + + + org.springframework.boot + spring-boot + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-web + + + org.projectlombok + lombok + provided + + + + mysql + mysql-connector-java + ${mysql.version} + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.statemachine + spring-statemachine-core + ${spring-statemachine.version} + + + io.projectreactor + reactor-core + ${reactor-core.version} + + + com.alibaba + transmittable-thread-local + ${transmittable-thread-local.version} + + + + + + + + + + + + + + + org.apache.httpcomponents.client5 + httpclient5 + ${http5.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + cn.hutool + hutool-all + ${hutool.version} + + + io.kubernetes + client-java + ${kubernetes.version} + + + org.freemarker + freemarker + ${freemarker.version} + + + com.alibaba.fastjson2 + fastjson2 + ${fastjson-version} + + + com.squareup.okhttp3 + okhttp + ${okhttp3.version} + + + org.mapstruct + mapstruct + ${mapstruct.version} + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + org.mapstruct + mapstruct-jdk8 + ${mapstruct.version} + + + com.qc.soft + deploy-ease-api + 1.0-SNAPSHOT + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + com.alibaba.nacos + nacos-client + + + + + com.qc.soft + deploy-ease + 1.0-SNAPSHOT + + + + \ No newline at end of file diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/DeployEaseApplication.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/DeployEaseApplication.java new file mode 100644 index 0000000..0611331 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/DeployEaseApplication.java @@ -0,0 +1,20 @@ +package com.qc.soft.deploy.ease; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.scheduling.annotation.EnableAsync; + +@SpringBootConfiguration +@EnableAutoConfiguration +@ComponentScan("com.qc.soft.deploy.ease.*") +//@MapperScan("com.qc.soft.longi.deployment.dao") +//@EnableScheduling +@EnableAsync +public class DeployEaseApplication { + + public static void main(String[] args) { + SpringApplication.run(DeployEaseApplication.class, args); + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/ApiResponse.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/ApiResponse.java new file mode 100644 index 0000000..2935943 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/ApiResponse.java @@ -0,0 +1,54 @@ +package com.qc.soft.deploy.ease.config; + +import com.qc.soft.deploy.ease.enums.BusinessErrorCode; +import lombok.Builder; +import lombok.ToString; + +import java.io.Serializable; +import java.util.StringJoiner; + +@Builder +@ToString +public class ApiResponse implements Serializable { + + private BusinessErrorCode code; + + private String message; + + private T data; + + public ApiResponse(BusinessErrorCode code, String message) { + this.code = code; + this.message = message; + } + + public ApiResponse(BusinessErrorCode code, String message, T data) { + this(code, message); + this.data = data; + } + + public BusinessErrorCode getCode() { + return code; + } + + public void setCode(BusinessErrorCode code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/DruidConfig.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/DruidConfig.java new file mode 100644 index 0000000..34c7182 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/DruidConfig.java @@ -0,0 +1,53 @@ + +package com.qc.soft.deploy.ease.config; + +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.support.http.StatViewServlet; +import com.alibaba.druid.support.http.WebStatFilter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.sql.DataSource; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +@Configuration +public class DruidConfig { + @ConfigurationProperties(prefix = "spring.datasource") + @Bean + public DataSource druid() { + return new DruidDataSource(); + } + + //配置 Druid 监控管理后台的Servlet; +//内置 Servlet 容器时没有web.xml文件,所以使用 Spring Boot 的注册 Servlet 方式 + @Bean + public ServletRegistrationBean statViewServlet() { + ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*"); + // 这些参数可以在 com.alibaba.druid.support.http.StatViewServlet 的父类 com.alibaba.druid.support.http.ResourceServlet 中找到 + Map initParams = new HashMap<>(); + initParams.put("loginUsername", "admin"); + initParams.put("loginPassword", "123456"); + initParams.put("allow", ""); //默认就是允许所有访问 + //deny:Druid 后台拒绝谁访问,表示禁止此ip访问 + // initParams.put("deny","192.168.10.132"); + bean.setInitParameters(initParams); + return bean; + } + + //2、配置一个web监控的filter + @Bean + public FilterRegistrationBean webStatFilter() { + FilterRegistrationBean bean = new FilterRegistrationBean(); + bean.setFilter(new WebStatFilter()); + Map initParams = new HashMap<>(); + initParams.put("exclusions", "*.js,*.css,/druid/*"); + bean.setInitParameters(initParams); + bean.setUrlPatterns(Arrays.asList("/*")); + return bean; + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/GlobalCorsConfig.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/GlobalCorsConfig.java new file mode 100644 index 0000000..d4aaf95 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/GlobalCorsConfig.java @@ -0,0 +1,23 @@ +package com.qc.soft.deploy.ease.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class GlobalCorsConfig { + @Bean + public WebMvcConfigurer corsConfigurer() { + return new WebMvcConfigurer() { + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") // 允许跨域的路径 + .allowedOrigins("*") // 允许跨域请求的域名 + .allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的请求方法 + .allowedHeaders("*") // 允许的请求头 + .allowCredentials(true); // 是否允许证书(cookies) + } + }; + } +} \ No newline at end of file diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/GlobalExceptionHandler.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/GlobalExceptionHandler.java new file mode 100644 index 0000000..294f1fa --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/GlobalExceptionHandler.java @@ -0,0 +1,25 @@ +package com.qc.soft.deploy.ease.config; + +import com.qc.soft.deploy.ease.enums.ResponseCode; +import com.qc.soft.deploy.ease.exception.BusinessException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import javax.servlet.http.HttpServletRequest; + +@RestControllerAdvice +@Slf4j +public class GlobalExceptionHandler { + + @Autowired + private HttpServletRequest httpServletRequest; + + @ExceptionHandler(BusinessException.class) + public ApiResponse parameterBodyMissingExceptionHandler(BusinessException exception) { + String requestURI = httpServletRequest.getRequestURI(); + log.error("An exception occurred while requesting an interface:{}", requestURI, exception); + return ApiResponse.builder().code(exception.getCode()).message(exception.getMessage()).build(); + } +} \ No newline at end of file diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/GlobalResponseHandler.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/GlobalResponseHandler.java new file mode 100644 index 0000000..b6a084c --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/GlobalResponseHandler.java @@ -0,0 +1,35 @@ +package com.qc.soft.deploy.ease.config; + +import com.qc.soft.deploy.ease.enums.ResponseCode; +import org.springframework.core.MethodParameter; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.server.ServerHttpResponse; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; + +@ControllerAdvice +public class GlobalResponseHandler implements ResponseBodyAdvice { + + @Override + public boolean supports(MethodParameter returnType, Class converterType) { + return true; + } + + @Override + public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, org.springframework.http.server.ServerHttpRequest request, ServerHttpResponse response) { + if (body instanceof ResponseEntity) { + return body; + } + if (body instanceof String) { + return body; + } + if (body == null) { + return ApiResponse.builder().code(ResponseCode.SUCCESS.getCode()).message(ResponseCode.SUCCESS.getMessage()).build(); + } + if (body instanceof ApiResponse) { + return body; + } + return ApiResponse.builder().data(body).code(ResponseCode.SUCCESS.getCode()).message(ResponseCode.SUCCESS.getMessage()).build(); + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/K8sRegistryPostProcessor.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/K8sRegistryPostProcessor.java new file mode 100644 index 0000000..b477c3d --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/K8sRegistryPostProcessor.java @@ -0,0 +1,77 @@ +package com.qc.soft.deploy.ease.config; + +import io.kubernetes.client.openapi.ApiClient; +import io.kubernetes.client.util.Config; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.Environment; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +import java.util.ArrayList; +import java.util.List; + + +@Configuration +@Slf4j +@Order(value = 100) +public class K8sRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware { + + private ApiClient apiClient; + + private ApplicationContext applicationContext; + + private final PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + + @Override + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { + initK8sApiClient(registry); +// registerDeploymentHolder(registry); + } + + private void initK8sApiClient(BeanDefinitionRegistry registry) { + log.info("Start registering the k8s client!!!"); + try { + Resource[] resources = resolver.getResources("classpath:/./kube/*"); + for (Resource resource : resources) { + if (!resource.isReadable() && StringUtils.isNotEmpty(resource.getFilename())) { + continue; + } + this.apiClient = Config.fromConfig(resource.getInputStream()); + BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(ApiClient.class, () -> apiClient).getBeanDefinition(); + registry.registerBeanDefinition("k8sApiClient", beanDefinition); + break; + } + } catch (Exception e) { + log.error("k8s client registration failed!!!", e); + throw new RuntimeException(e); + } + } + + @Override + public void afterPropertiesSet() { + Environment environment = applicationContext.getEnvironment(); +// this.k8sBoundNamespaces = environment.getProperty("devops.k8s.namespaces", List.class); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/WebMvcConfig.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/WebMvcConfig.java new file mode 100644 index 0000000..8191219 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/config/WebMvcConfig.java @@ -0,0 +1,40 @@ +package com.qc.soft.deploy.ease.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.qc.soft.deploy.ease.interceptor.TenantInterceptor; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +import javax.annotation.Resource; +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; +import java.util.List; + +@Configuration +public class WebMvcConfig extends WebMvcConfigurerAdapter { + + + @Resource + private TenantInterceptor tenantInterceptor; + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(tenantInterceptor).addPathPatterns("/**"); + } + + @Override + public void configureMessageConverters(List> converters) { + converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8)); + ObjectMapper mapper = new ObjectMapper(); + mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); + mapper.registerModule(new JavaTimeModule()); + mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); + converters.add(new MappingJackson2HttpMessageConverter(mapper)); + super.configureMessageConverters(converters); + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/context/TenantContext.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/context/TenantContext.java new file mode 100644 index 0000000..8745edd --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/context/TenantContext.java @@ -0,0 +1,19 @@ +package com.qc.soft.deploy.ease.context; + +import com.alibaba.ttl.TransmittableThreadLocal; + +public class TenantContext { + private static final TransmittableThreadLocal currentTenant = new TransmittableThreadLocal<>(); + + public static void setCurrentTenant(String tenant) { + currentTenant.set(tenant); + } + + public static String getCurrentTenant() { + return currentTenant.get(); + } + + public static void clear() { + currentTenant.remove(); + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/controller/NacosController.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/controller/NacosController.java new file mode 100644 index 0000000..f53f955 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/controller/NacosController.java @@ -0,0 +1,26 @@ +package com.qc.soft.deploy.ease.controller; + +import com.qc.soft.deploy.ease.api.controller.INacosController; +import com.qc.soft.deploy.ease.service.INacosService; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +@RestController +@RequestMapping("/deploy-ease/nacos") +public class NacosController implements INacosController { + + + @Resource + private INacosService nacosService; + + + @Override + @GetMapping("/instances") + public void instances() { + nacosService.instances(); + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/K8sNamespaceConvert.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/K8sNamespaceConvert.java new file mode 100644 index 0000000..0531c9a --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/K8sNamespaceConvert.java @@ -0,0 +1,23 @@ +package com.qc.soft.deploy.ease.convert; + +import com.qc.soft.deploy.ease.k8s.K8sNamespaceResponse; +import io.kubernetes.client.openapi.models.V1Namespace; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface K8sNamespaceConvert { + + K8sNamespaceConvert INSTANCE = Mappers.getMapper(K8sNamespaceConvert.class); + + + @Mappings({@Mapping(source = "metadata.name", target = "name"),}) + K8sNamespaceResponse toK8sNamespaceResponse(V1Namespace namespace); + + List toK8sNamespaceList(List namespaces); + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/K8sPodConvert.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/K8sPodConvert.java new file mode 100644 index 0000000..35b3618 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/K8sPodConvert.java @@ -0,0 +1,29 @@ +package com.qc.soft.deploy.ease.convert; + +import com.qc.soft.deploy.ease.k8s.K8sPodResponse; +import io.kubernetes.client.openapi.models.V1Pod; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface K8sPodConvert { + + K8sPodConvert INSTANCE = Mappers.getMapper(K8sPodConvert.class); + + + @Mappings({ + @Mapping(source = "v1Pod.metadata.namespace", target = "namespace"), + @Mapping(source = "v1Pod.metadata.name", target = "name"), + @Mapping(target = "v1Pod.imageName", expression = "java(v1Pod.getSpec().getContainers().get(0).getImage())"), + @Mapping(target = "deploymentName", source = "deploymentName"), + @Mapping(target = "container", expression = "java(v1Pod.getSpec().getContainers().get(0).getName())"), + @Mapping(target = "creationTimestamp", source = "v1Pod.metadata.creationTimestamp"), + @Mapping(target = "restartCount", expression = "java(v1Pod.getStatus().getContainerStatuses() == null ? 0 : v1Pod.getStatus().getContainerStatuses().get(0).getRestartCount())"), + @Mapping(target = "limits", expression = "java(v1Pod.getSpec().getContainers().get(0).getResources().getLimits() == null ? null : v1Pod.getSpec().getContainers().get(0).getResources().getLimits().get(\"memory\").getNumber())"), + @Mapping(target = "requests", expression = "java(v1Pod.getSpec().getContainers().get(0).getResources().getRequests() == null ? null : v1Pod.getSpec().getContainers().get(0).getResources().getRequests().get(\"memory\").getNumber())") + }) + K8sPodResponse toK8sPodResponse(V1Pod v1Pod, String deploymentName); + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/api/response/DictionaryApiResponseConvert.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/api/response/DictionaryApiResponseConvert.java new file mode 100644 index 0000000..57bb953 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/api/response/DictionaryApiResponseConvert.java @@ -0,0 +1,18 @@ +package com.qc.soft.deploy.ease.convert.api.response; + +import com.qc.soft.deploy.ease.api.response.DictionaryResponse; +import com.qc.soft.deploy.ease.entity.Dictionary; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface DictionaryApiResponseConvert { + + DictionaryApiResponseConvert INSTANCE = Mappers.getMapper(DictionaryApiResponseConvert.class); + + + List entityToResponse(List dictionaries); + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/api/response/ProjectApiResponseConvert.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/api/response/ProjectApiResponseConvert.java new file mode 100644 index 0000000..b426aaa --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/api/response/ProjectApiResponseConvert.java @@ -0,0 +1,18 @@ +package com.qc.soft.deploy.ease.convert.api.response; + +import com.qc.soft.deploy.ease.api.response.ProjectResponse; +import com.qc.soft.deploy.ease.entity.Project; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface ProjectApiResponseConvert { + + ProjectApiResponseConvert INSTANCE = Mappers.getMapper(ProjectApiResponseConvert.class); + + + List entityToResponse(List projects); + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/api/response/TenantDictionaryApiResponseConvert.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/api/response/TenantDictionaryApiResponseConvert.java new file mode 100644 index 0000000..09bbc74 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/api/response/TenantDictionaryApiResponseConvert.java @@ -0,0 +1,18 @@ +package com.qc.soft.deploy.ease.convert.api.response; + +import com.qc.soft.deploy.ease.api.response.TenantDictionaryResponse; +import com.qc.soft.deploy.ease.entity.TenantDictionary; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface TenantDictionaryApiResponseConvert { + + TenantDictionaryApiResponseConvert INSTANCE = Mappers.getMapper(TenantDictionaryApiResponseConvert.class); + + + List entityToResponse(List dictionaries); + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/dto/DictionaryConvert.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/dto/DictionaryConvert.java new file mode 100644 index 0000000..8901e2c --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/convert/dto/DictionaryConvert.java @@ -0,0 +1,23 @@ +package com.qc.soft.deploy.ease.convert.dto; + +import com.qc.soft.deploy.ease.convert.K8sNamespaceConvert; +import com.qc.soft.deploy.ease.entity.Dictionary; +import com.qc.soft.deploy.ease.entity.TenantDictionary; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface DictionaryConvert { + + DictionaryConvert INSTANCE = Mappers.getMapper(DictionaryConvert.class); + + + @Mappings( + @Mapping(target = "tenantCode", expression = "java(com.qc.soft.deploy.ease.context.TenantContext.getCurrentTenant())") + ) + TenantDictionary systemDictionaryToTenantDictionary(Dictionary dictionary); + + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/BaseEntity.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/BaseEntity.java new file mode 100644 index 0000000..ec13a33 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/BaseEntity.java @@ -0,0 +1,28 @@ +package com.qc.soft.deploy.ease.entity; + +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; +import java.io.Serializable; +import java.time.LocalDateTime; + + +@MappedSuperclass +public abstract class BaseEntity implements Serializable { + + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, updatable = false) + private LocalDateTime createTime; + + @Column(nullable = false) + private LocalDateTime updateTime; + + private Boolean isDeleted; + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/Dictionary.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/Dictionary.java new file mode 100644 index 0000000..86295d6 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/Dictionary.java @@ -0,0 +1,35 @@ +package com.qc.soft.deploy.ease.entity; + + +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import java.util.Date; + +@EqualsAndHashCode(callSuper = true) +@Table(name = "dictionary") +@Entity +@Data +public class Dictionary extends BaseEntity { + + @Column(name = "dictionary_code") + private String code; + + @Column(name = "dictionary_name") + private String name; + + @Column(name = "dictionary_value") + private String value; + + private boolean status; + + @Column(name = "tenant_sharing") + private boolean tenantSharing; + +} \ No newline at end of file diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/Project.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/Project.java new file mode 100644 index 0000000..4d2cd41 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/Project.java @@ -0,0 +1,26 @@ +package com.qc.soft.deploy.ease.entity; + + +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; + +@EqualsAndHashCode(callSuper = true) +@Table(name = "project") +@Entity +@Data +public class Project extends BaseEntity { + + @Column(name = "project_code") + private String projectCode; + + @Column(name = "project_name") + private String projectName; + + @Column(name = "tenant_code") + private String tenantCode; + +} \ No newline at end of file diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/Tenant.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/Tenant.java new file mode 100644 index 0000000..c8b79ce --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/Tenant.java @@ -0,0 +1,25 @@ +package com.qc.soft.deploy.ease.entity; + + +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; + +@EqualsAndHashCode(callSuper = true) +@Table(name = "tenant") +@Entity +@Data +public class Tenant extends BaseEntity { + + @Column(name = "tenant_code") + private String tenantCode; + + @Column(name = "tenant_name") + private String tenantName; + + private boolean enabled; + +} \ No newline at end of file diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/TenantDictionary.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/TenantDictionary.java new file mode 100644 index 0000000..ddf8e55 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/TenantDictionary.java @@ -0,0 +1,31 @@ +package com.qc.soft.deploy.ease.entity; + + +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; + +@EqualsAndHashCode(callSuper = true) +@Table(name = "tenant_dictionary") +@Entity +@Data +public class TenantDictionary extends BaseEntity { + + @Column(name = "dictionary_code") + private String code; + + @Column(name = "dictionary_name") + private String name; + + @Column(name = "dictionary_value") + private String value; + + private boolean status; + + @Column(name = "tenant_code") + private String tenantCode; + +} \ No newline at end of file diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/User.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/User.java new file mode 100644 index 0000000..7ba6646 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/entity/User.java @@ -0,0 +1,29 @@ +package com.qc.soft.deploy.ease.entity; + + +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import java.util.Date; + +@EqualsAndHashCode(callSuper = true) +@Table(name = "user") +@Entity +@Data +public class User extends BaseEntity { + + @Column(name = "user_name") + private String username; + + private String password; + + private String realName; + +} \ No newline at end of file diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/enums/BusinessErrorCode.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/enums/BusinessErrorCode.java new file mode 100644 index 0000000..29ee00e --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/enums/BusinessErrorCode.java @@ -0,0 +1,21 @@ +package com.qc.soft.deploy.ease.enums; + +public enum BusinessErrorCode { + + SUCCESS("操作成功"), + FAILURE("操作失败"), + TENANT_DOES_NOT_EXIST("租户不存在"), + + TENANT_NOT_ENABLED("%s租户未启用"); + + + private String message; + + BusinessErrorCode(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/enums/JenkinsJobStatus.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/enums/JenkinsJobStatus.java new file mode 100644 index 0000000..28fa291 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/enums/JenkinsJobStatus.java @@ -0,0 +1,21 @@ +package com.qc.soft.deploy.ease.enums; + +import lombok.Getter; + +@Getter +public enum JenkinsJobStatus { + + WAITING_BUILD("等待构建"), + BUILDING("构建中"), + BUILD_END("构建完成"); + + private final String message; + + JenkinsJobStatus(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/enums/ResponseCode.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/enums/ResponseCode.java new file mode 100644 index 0000000..c8e7e44 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/enums/ResponseCode.java @@ -0,0 +1,21 @@ +package com.qc.soft.deploy.ease.enums; + +import lombok.Getter; + +@Getter +public enum ResponseCode { + + SUCCESS(BusinessErrorCode.SUCCESS, BusinessErrorCode.SUCCESS.getMessage()), + FAILURE(BusinessErrorCode.FAILURE, BusinessErrorCode.FAILURE.getMessage()), + TENANT_DOES_NOT_EXIST(BusinessErrorCode.TENANT_DOES_NOT_EXIST, BusinessErrorCode.TENANT_DOES_NOT_EXIST.getMessage()); + + private final BusinessErrorCode code; + + private final String message; + + ResponseCode(BusinessErrorCode code, String message) { + this.code = code; + this.message = message; + } + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/event/JenkinsJobChangeEvent.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/event/JenkinsJobChangeEvent.java new file mode 100644 index 0000000..480dc78 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/event/JenkinsJobChangeEvent.java @@ -0,0 +1,21 @@ +package com.qc.soft.deploy.ease.event; + +import lombok.Getter; + +@Getter +public enum JenkinsJobChangeEvent { + + SUCCESS("成功"), + FAILURE("失败"), + ABORTED("终止"); + + private final String message; + + JenkinsJobChangeEvent(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/exception/BusinessException.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/exception/BusinessException.java new file mode 100644 index 0000000..5808ef2 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/exception/BusinessException.java @@ -0,0 +1,27 @@ +package com.qc.soft.deploy.ease.exception; + +import com.qc.soft.deploy.ease.enums.BusinessErrorCode; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Setter +@Builder +public class BusinessException extends RuntimeException { + + @Getter + protected BusinessErrorCode code; + + protected String message; + + public BusinessException(BusinessErrorCode code, String message, Throwable e) { + super(message, e); + this.code = code; + this.message = message; + } + + public BusinessException(BusinessErrorCode code, String message) { + this(code, message, null); + } + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/fegin/response/JenkinsJobChangeSetDetailResponse.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/fegin/response/JenkinsJobChangeSetDetailResponse.java new file mode 100644 index 0000000..c3c2a5c --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/fegin/response/JenkinsJobChangeSetDetailResponse.java @@ -0,0 +1,29 @@ +package com.qc.soft.deploy.ease.fegin.response; + +import lombok.Data; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +@Data +public class JenkinsJobChangeSetDetailResponse { + + private String commitId; + + private Date timestamp; + + private Map author; + + private String authorEmail; + + private String comment; + + private Date date; + + private String id; + + private String msg; + + private List> paths; +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/fegin/response/JenkinsJobChangeSetResponse.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/fegin/response/JenkinsJobChangeSetResponse.java new file mode 100644 index 0000000..f03ee0a --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/fegin/response/JenkinsJobChangeSetResponse.java @@ -0,0 +1,12 @@ +package com.qc.soft.deploy.ease.fegin.response; + +import lombok.Data; + +import java.util.List; + +@Data +public class JenkinsJobChangeSetResponse { + + private List items; + +} \ No newline at end of file diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/fegin/response/JenkinsJobResponse.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/fegin/response/JenkinsJobResponse.java new file mode 100644 index 0000000..5710397 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/fegin/response/JenkinsJobResponse.java @@ -0,0 +1,36 @@ +package com.qc.soft.deploy.ease.fegin.response; + +import com.qc.soft.deploy.ease.enums.JenkinsJobStatus; +import lombok.Data; +import lombok.ToString; + +import java.util.Date; + +@Data +@ToString +public class JenkinsJobResponse { + + private Long id; + + private String projectName; + + private int number; + + private boolean inProgress; + + private boolean building; + + private JenkinsJobStatus result; + + private Date timestamp; + + private long duration; + + private int queueId; + + private JenkinsJobChangeSetResponse changeSet; + +} + + + diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/holder/K8sApiHolder.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/holder/K8sApiHolder.java new file mode 100644 index 0000000..b29c2bc --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/holder/K8sApiHolder.java @@ -0,0 +1,166 @@ +package com.qc.soft.deploy.ease.holder; + +import com.qc.soft.deploy.ease.convert.K8sNamespaceConvert; +import com.qc.soft.deploy.ease.convert.K8sPodConvert; +import com.qc.soft.deploy.ease.k8s.K8sDeploymentResponse; +import com.qc.soft.deploy.ease.k8s.K8sNamespaceResponse; +import com.qc.soft.deploy.ease.k8s.K8sPodResponse; +import io.kubernetes.client.Metrics; +import io.kubernetes.client.custom.PodMetrics; +import io.kubernetes.client.custom.PodMetricsList; +import io.kubernetes.client.custom.Quantity; +import io.kubernetes.client.openapi.ApiClient; +import io.kubernetes.client.openapi.ApiException; +import io.kubernetes.client.openapi.apis.AppsV1Api; +import io.kubernetes.client.openapi.apis.CoreV1Api; +import io.kubernetes.client.openapi.models.V1Deployment; +import io.kubernetes.client.openapi.models.V1DeploymentList; +import io.kubernetes.client.openapi.models.V1DeploymentSpec; +import io.kubernetes.client.openapi.models.V1Namespace; +import io.kubernetes.client.openapi.models.V1NamespaceList; +import io.kubernetes.client.openapi.models.V1ObjectMeta; +import io.kubernetes.client.openapi.models.V1Pod; +import io.kubernetes.client.openapi.models.V1PodList; +import io.kubernetes.client.openapi.models.V1Scale; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +@Component +@Slf4j +public class K8sApiHolder { + + @Resource + private ApiClient apiClient; + + public void resetNamespacedDeploymentScale(String namespace, String deploymentName, Integer clearScaleNumber, Integer scaleNumber) throws ApiException, InterruptedException { + AppsV1Api api = new AppsV1Api(apiClient); + updateNamespacedDeploymentScale(api, namespace, deploymentName, clearScaleNumber); + Thread.sleep(2000); + updateNamespacedDeploymentScale(api, namespace, deploymentName, scaleNumber); + } + + private void updateNamespacedDeploymentScale(AppsV1Api api, String namespace, String deploymentName, Integer scaleNumber) throws ApiException { + V1Scale v1Scale = api.readNamespacedDeploymentScale(deploymentName, namespace, null); + if (v1Scale.getSpec() == null) { + log.error("K8s query scale is empty, unable to scale operations, namespace:{}, deployment:{}", namespace, deploymentName); + return; + } + v1Scale.getSpec().setReplicas(scaleNumber); + V1Scale scaleUpdated = api.replaceNamespacedDeploymentScale(deploymentName, namespace, v1Scale, null, null, null, null); + if (scaleUpdated == null) { + return; + } + Integer replicas = Objects.requireNonNull(scaleUpdated.getSpec()).getReplicas(); + if (replicas == null && scaleNumber == 0) { + log.info("K8s namespace:{}, deployment:{} pods scaling is complete, scaleNumber:{}", namespace, deploymentName, scaleNumber); + return; + } + if (Objects.equals(replicas, scaleNumber)) { + log.info("K8s namespace:{}, deployment:{} pods scaling is complete, scaleNumber:{}", namespace, deploymentName, scaleNumber); + } else { + log.error("K8s namespace:{}, deployment:{} pods scaling failure, scaleNumber:{}", namespace, deploymentName, scaleNumber); + } + } + + public List deploymentList(String namespace) { + try { + List responses = new ArrayList<>(); + AppsV1Api api = new AppsV1Api(apiClient); + V1DeploymentList deploymentList = api.listNamespacedDeployment(namespace, null, null, null, null, null, null, null, null, null, null, null); + for (V1Deployment deployment : deploymentList.getItems()) { + V1ObjectMeta metadata = deployment.getMetadata(); + V1DeploymentSpec spec = deployment.getSpec(); + K8sDeploymentResponse response = new K8sDeploymentResponse(); + response.setName(Objects.requireNonNull(metadata).getName()); + response.setNamespace(metadata.getNamespace()); + response.setCreationTimestamp(metadata.getCreationTimestamp()); + response.setReplicas(Objects.requireNonNull(spec).getReplicas()); + response.setImageName(deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getImage()); + responses.add(response); + } + return responses; + } catch (ApiException e) { + throw new RuntimeException(e); + } + } + + public List podsList(String namespace, String deploymentName) { + try { + CoreV1Api api = new CoreV1Api(apiClient); + V1PodList v1PodList = api.listNamespacedPod(namespace, null, null, null, null, null, null, null, null, null, null, null); + List results = new ArrayList<>(); + List list = new ArrayList<>(); + for (V1Pod pod : v1PodList.getItems()) { + V1ObjectMeta metadata = pod.getMetadata(); + if (StringUtils.isEmpty(deploymentName)) { + results.add(K8sPodConvert.INSTANCE.toK8sPodResponse(pod, deploymentName)); + } else { + if (metadata.getName().contains(deploymentName)) { + results.add(K8sPodConvert.INSTANCE.toK8sPodResponse(pod, deploymentName)); + } + } + } + if (CollectionUtils.isEmpty(results)) { + return new ArrayList<>(); + } + Metrics metrics = new Metrics(apiClient); + PodMetricsList podMetrics = metrics.getPodMetrics(namespace); + results.forEach(pod -> { + Optional metricsOptional = podMetrics.getItems().stream().filter(item -> item.getMetadata().getName().equals(pod.getName())).findFirst(); + if (!metricsOptional.isPresent()) { + return; + } + Map usage = metricsOptional.get().getContainers().get(0).getUsage(); + pod.setCpuUsage(usage.get("cpu").getNumber()); + pod.setMemoryUsage(usage.get("memory").getNumber()); + }); + return results; + } catch (ApiException e) { + throw new RuntimeException(e); + } + } + + public String getPodLog(String namespace, String podName) { + try { + CoreV1Api api = new CoreV1Api(apiClient); + String podLog = api.readNamespacedPodLog( + podName, + namespace, + "backend-longi-scp-meta-group-1", + false, + null, + 102400, + "true", + false, + 10, + 10, + true); + System.out.println(podLog); + return podLog; + } catch (ApiException e) { + throw new RuntimeException(e); + } + } + + public List namespaceList() { + try { + List namespaces = new ArrayList<>(); + CoreV1Api api = new CoreV1Api(apiClient); + V1NamespaceList v1NamespaceList = api.listNamespace(null, null, null, null, null, null, null, null, null, null, null); + namespaces.addAll(v1NamespaceList.getItems()); + return K8sNamespaceConvert.INSTANCE.toK8sNamespaceList(namespaces); + + } catch (ApiException e) { + throw new RuntimeException(e); + } + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/interceptor/TenantInterceptor.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/interceptor/TenantInterceptor.java new file mode 100644 index 0000000..862b665 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/interceptor/TenantInterceptor.java @@ -0,0 +1,48 @@ +package com.qc.soft.deploy.ease.interceptor; + +import com.qc.soft.deploy.ease.context.TenantContext; +import com.qc.soft.deploy.ease.entity.Tenant; +import com.qc.soft.deploy.ease.exception.BusinessException; +import com.qc.soft.deploy.ease.repository.ITenantRepository; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import static com.qc.soft.deploy.ease.enums.BusinessErrorCode.TENANT_DOES_NOT_EXIST; +import static com.qc.soft.deploy.ease.enums.BusinessErrorCode.TENANT_NOT_ENABLED; + +@Slf4j +@Component +public class TenantInterceptor implements HandlerInterceptor { + + @Resource + private ITenantRepository tenantRepository; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + String tenantCode = request.getHeader("x-tenant-code"); + if (null == tenantCode || StringUtils.isEmpty(tenantCode)) { + throw new BusinessException(TENANT_DOES_NOT_EXIST, "请求头未携带:x-tenant-code"); + } + Tenant tenant = tenantRepository.findByTenantCode(tenantCode); + if (tenant == null) { + throw new BusinessException(TENANT_DOES_NOT_EXIST, TENANT_DOES_NOT_EXIST.getMessage()); + } + if (!tenant.isEnabled()) { + throw new BusinessException(TENANT_NOT_ENABLED, String.format(TENANT_NOT_ENABLED.getMessage(), tenantCode)); + } + TenantContext.setCurrentTenant(tenantCode); + return true; + } + + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + TenantContext.clear(); + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/k8s/K8sAuthentications.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/k8s/K8sAuthentications.java new file mode 100644 index 0000000..49bcfcd --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/k8s/K8sAuthentications.java @@ -0,0 +1,10 @@ +package com.qc.soft.deploy.ease.k8s; + +import lombok.Data; + +import java.time.OffsetDateTime; + +@Data +public class K8sAuthentications { + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/k8s/K8sDeploymentResponse.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/k8s/K8sDeploymentResponse.java new file mode 100644 index 0000000..e24c47d --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/k8s/K8sDeploymentResponse.java @@ -0,0 +1,22 @@ +package com.qc.soft.deploy.ease.k8s; + +import lombok.Data; + +import java.time.OffsetDateTime; + +@Data +public class K8sDeploymentResponse { + + private String namespace; + + private String name; + + private String realName; + + private Integer replicas; + + private OffsetDateTime creationTimestamp; + + private String imageName; + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/k8s/K8sNamespaceResponse.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/k8s/K8sNamespaceResponse.java new file mode 100644 index 0000000..4dbc6ee --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/k8s/K8sNamespaceResponse.java @@ -0,0 +1,12 @@ +package com.qc.soft.deploy.ease.k8s; + +import lombok.Data; + +import java.time.OffsetDateTime; + +@Data +public class K8sNamespaceResponse { + + private String name; + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/k8s/K8sPodResponse.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/k8s/K8sPodResponse.java new file mode 100644 index 0000000..ac96ed6 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/k8s/K8sPodResponse.java @@ -0,0 +1,33 @@ +package com.qc.soft.deploy.ease.k8s; + +import lombok.Data; + +import java.math.BigDecimal; +import java.time.OffsetDateTime; + +@Data +public class K8sPodResponse { + + private String namespace; + + private String deploymentName; + + private String name; + + private String container; + + private BigDecimal limits; + + private BigDecimal requests; + + private Integer restartCount; + + private BigDecimal cpuUsage; + + private BigDecimal memoryUsage; + + private String imageName; + + private OffsetDateTime creationTimestamp; + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/repository/IDictionaryRepository.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/repository/IDictionaryRepository.java new file mode 100644 index 0000000..873350b --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/repository/IDictionaryRepository.java @@ -0,0 +1,13 @@ +package com.qc.soft.deploy.ease.repository; + +import com.qc.soft.deploy.ease.entity.Dictionary; +import com.qc.soft.deploy.ease.entity.User; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface IDictionaryRepository extends JpaRepository { + + List findAll(); + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/repository/IProjectRepository.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/repository/IProjectRepository.java new file mode 100644 index 0000000..9d10d60 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/repository/IProjectRepository.java @@ -0,0 +1,12 @@ +package com.qc.soft.deploy.ease.repository; + +import com.qc.soft.deploy.ease.entity.Project; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface IProjectRepository extends JpaRepository { + + List findByTenantCode(String tenantCode); + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/repository/ITenantDictionaryRepository.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/repository/ITenantDictionaryRepository.java new file mode 100644 index 0000000..c1a91ca --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/repository/ITenantDictionaryRepository.java @@ -0,0 +1,13 @@ +package com.qc.soft.deploy.ease.repository; + +import com.qc.soft.deploy.ease.entity.Dictionary; +import com.qc.soft.deploy.ease.entity.TenantDictionary; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ITenantDictionaryRepository extends JpaRepository { + + List findAllByTenantCode(String tenantCode); + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/repository/ITenantRepository.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/repository/ITenantRepository.java new file mode 100644 index 0000000..82c8b74 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/repository/ITenantRepository.java @@ -0,0 +1,13 @@ +package com.qc.soft.deploy.ease.repository; + +import com.qc.soft.deploy.ease.entity.Dictionary; +import com.qc.soft.deploy.ease.entity.Tenant; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ITenantRepository extends JpaRepository { + + Tenant findByTenantCode(String tenantCode); + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/repository/IUserRepository.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/repository/IUserRepository.java new file mode 100644 index 0000000..d524797 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/repository/IUserRepository.java @@ -0,0 +1,8 @@ +package com.qc.soft.deploy.ease.repository; + +import com.qc.soft.deploy.ease.entity.User; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface IUserRepository extends JpaRepository { + User findByUsernameAndPassword(String username, String password); +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/IDictionaryService.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/IDictionaryService.java new file mode 100644 index 0000000..17aa9d3 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/IDictionaryService.java @@ -0,0 +1,14 @@ +package com.qc.soft.deploy.ease.service; + +import com.qc.soft.deploy.ease.api.response.DictionaryResponse; +import com.qc.soft.deploy.ease.api.response.TenantDictionaryResponse; + +import java.util.List; + +public interface IDictionaryService { + + + List findSystemDicts(); + + List findDictsByTenantCode(); +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/IJenkinsService.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/IJenkinsService.java new file mode 100644 index 0000000..c3f9fca --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/IJenkinsService.java @@ -0,0 +1,14 @@ +package com.qc.soft.deploy.ease.service; + +import com.qc.soft.deploy.ease.fegin.response.JenkinsJobResponse; + +import java.util.Map; + +public interface IJenkinsService { + JenkinsJobResponse create(); + + //获取订单列表 + Map getJenkinsJobs(); + + JenkinsJobResponse pay(long id); +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/IK8sService.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/IK8sService.java new file mode 100644 index 0000000..0738103 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/IK8sService.java @@ -0,0 +1,21 @@ +package com.qc.soft.deploy.ease.service; + +import com.qc.soft.deploy.ease.k8s.K8sDeploymentResponse; +import com.qc.soft.deploy.ease.k8s.K8sNamespaceResponse; +import com.qc.soft.deploy.ease.k8s.K8sPodResponse; + +import java.util.List; + +public interface IK8sService { + + + List deployments(String namespace); + + String getPodLog(String namespace, String podName); + + List pods(String namespace, String deploymentName); + + List namespaces(); + + String getKubeConfig(); +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/INacosService.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/INacosService.java new file mode 100644 index 0000000..434dcc6 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/INacosService.java @@ -0,0 +1,6 @@ +package com.qc.soft.deploy.ease.service; + +public interface INacosService { + + void instances(); +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/IProjectService.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/IProjectService.java new file mode 100644 index 0000000..d2c54f7 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/IProjectService.java @@ -0,0 +1,11 @@ +package com.qc.soft.deploy.ease.service; + +import com.qc.soft.deploy.ease.api.response.ProjectResponse; + +import java.util.List; + +public interface IProjectService { + + + List list(); +} \ No newline at end of file diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/IUserService.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/IUserService.java new file mode 100644 index 0000000..a463cba --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/IUserService.java @@ -0,0 +1,7 @@ +package com.qc.soft.deploy.ease.service; + +public interface IUserService { + + + boolean login(String username, String password); +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/DictionaryServiceImpl.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/DictionaryServiceImpl.java new file mode 100644 index 0000000..9dd60cc --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/DictionaryServiceImpl.java @@ -0,0 +1,55 @@ +package com.qc.soft.deploy.ease.service.impl; + +import com.qc.soft.deploy.ease.api.response.DictionaryResponse; +import com.qc.soft.deploy.ease.api.response.TenantDictionaryResponse; +import com.qc.soft.deploy.ease.context.TenantContext; +import com.qc.soft.deploy.ease.convert.api.response.DictionaryApiResponseConvert; +import com.qc.soft.deploy.ease.convert.api.response.TenantDictionaryApiResponseConvert; +import com.qc.soft.deploy.ease.convert.dto.DictionaryConvert; +import com.qc.soft.deploy.ease.entity.Dictionary; +import com.qc.soft.deploy.ease.entity.TenantDictionary; +import com.qc.soft.deploy.ease.repository.IDictionaryRepository; +import com.qc.soft.deploy.ease.repository.ITenantDictionaryRepository; +import com.qc.soft.deploy.ease.service.IDictionaryService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class DictionaryServiceImpl implements IDictionaryService { + + + @Resource + private IDictionaryRepository dictionaryRepository; + + @Resource + private ITenantDictionaryRepository tenantDictionaryRepository; + + + @Override + public List findSystemDicts() { + return DictionaryApiResponseConvert.INSTANCE.entityToResponse(dictionaryRepository.findAll()); + } + + @Override + public List findDictsByTenantCode() { + String tenantCode = TenantContext.getCurrentTenant(); + List tenantSharingDict = dictionaryRepository.findAll().stream().filter(Dictionary::isTenantSharing).collect(Collectors.toList()); + List tenantDict = tenantDictionaryRepository.findAllByTenantCode(tenantCode); + List mergeTenantDict = new ArrayList<>(); + tenantSharingDict.forEach(v -> { + String systemDictCode = v.getCode(); + Map tenantDictMap = tenantDict.stream().collect(Collectors.toMap(TenantDictionary::getCode, tenantDictionary -> tenantDictionary)); + TenantDictionary tenantDictionary = tenantDictMap.get(systemDictCode); + if (tenantDictionary == null) { + tenantDictMap.put(systemDictCode, DictionaryConvert.INSTANCE.systemDictionaryToTenantDictionary(v)); + } + mergeTenantDict.addAll(tenantDictMap.values()); + }); + return TenantDictionaryApiResponseConvert.INSTANCE.entityToResponse(mergeTenantDict); + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/JenkinsServiceImpl.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/JenkinsServiceImpl.java new file mode 100644 index 0000000..669f074 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/JenkinsServiceImpl.java @@ -0,0 +1,81 @@ +package com.qc.soft.deploy.ease.service.impl; + +import com.qc.soft.deploy.ease.fegin.response.JenkinsJobResponse; +import com.qc.soft.deploy.ease.event.JenkinsJobChangeEvent; +import com.qc.soft.deploy.ease.enums.JenkinsJobStatus; +import com.qc.soft.deploy.ease.service.IJenkinsService; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.statemachine.StateMachine; +import org.springframework.statemachine.persist.StateMachinePersister; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; + +@Service +public class JenkinsServiceImpl implements IJenkinsService { + + + @Resource + private StateMachine jenkinsStateMachine; + + + @Resource + private StateMachinePersister persister; + + private int id = 1; + + private Map jenkinsJobs = new HashMap<>(); + + @Override + public JenkinsJobResponse create() { + JenkinsJobResponse jenkinsJob = new JenkinsJobResponse(); + jenkinsJob.setResult(JenkinsJobStatus.WAITING_BUILD);//设置订单的初始状态 + jenkinsJob.setId((long) id++);//设置订单的编号,累加 + jenkinsJobs.put(jenkinsJob.getId(), jenkinsJob);//根据编号对应地存储订单对象,便于存取 + System.out.println("订单创建成功" + jenkinsJob.toString()); + return jenkinsJob;//返回创建好的订单对象 + } + + //获取订单列表 + @Override + public Map getJenkinsJobs() { + return jenkinsJobs; + } + + + private synchronized boolean sendEvent(Message message, JenkinsJobResponse jenkinsJobResponse) { + boolean result = false; + try { + jenkinsStateMachine.start(); + //尝试恢复状态机状态 + persister.restore(jenkinsStateMachine, jenkinsJobResponse); + //添加延迟用于线程安全测试 + Thread.sleep(1000); + result = jenkinsStateMachine.sendEvent(message); + //持久化状态机状态 + persister.persist(jenkinsStateMachine, jenkinsJobResponse); + } catch (Exception e) { + e.printStackTrace(); + } finally { + jenkinsStateMachine.stop(); + } + return result; + } + + @Override + public JenkinsJobResponse pay(long id) { + + /*根据id获取订单集合的指定订单*/ + JenkinsJobResponse jenkinsJobResponse = jenkinsJobs.get(id); + Message message = MessageBuilder.withPayload(JenkinsJobChangeEvent.SUCCESS).setHeader("jenkinsJobResponse", jenkinsJobResponse).build(); + + if (!sendEvent(message, jenkinsJobResponse)) { + System.out.println("订单支付失败"); + } + + return jenkinsJobResponse; + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/K8sServiceImpl.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/K8sServiceImpl.java new file mode 100644 index 0000000..8bbb9ec --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/K8sServiceImpl.java @@ -0,0 +1,64 @@ +package com.qc.soft.deploy.ease.service.impl; + +import com.qc.soft.deploy.ease.k8s.K8sDeploymentResponse; +import com.qc.soft.deploy.ease.k8s.K8sNamespaceResponse; +import com.qc.soft.deploy.ease.k8s.K8sPodResponse; +import com.qc.soft.deploy.ease.holder.K8sApiHolder; +import com.qc.soft.deploy.ease.service.IK8sService; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class K8sServiceImpl implements IK8sService { + + + @Resource + private K8sApiHolder k8sApiHolder; + + private final PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + + + @Override + public List deployments(String namespace) { + return k8sApiHolder.deploymentList(namespace); + } + + @Override + public String getPodLog(String namespace, String podName) { + return k8sApiHolder.getPodLog(namespace, podName); + } + + @Override + public List pods(String namespace, String deploymentName) { + return k8sApiHolder.podsList(namespace, deploymentName); + } + + @Override + public List namespaces() { + return k8sApiHolder.namespaceList().stream().filter(namespace -> namespace.getName().contains("ibp")).collect(Collectors.toList()); + } + + @Override + public String getKubeConfig() { + try { + org.springframework.core.io.Resource[] resources = resolver.getResources("classpath:/./kube/*"); + for (org.springframework.core.io.Resource resource : resources) { + if (!resource.isReadable() && StringUtils.isNotEmpty(resource.getFilename())) { + continue; + } + return IOUtils.toString(resource.getInputStream(), StandardCharsets.UTF_8); + } + return null; + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/NacosServiceImpl.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/NacosServiceImpl.java new file mode 100644 index 0000000..5aca0f3 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/NacosServiceImpl.java @@ -0,0 +1,33 @@ +package com.qc.soft.deploy.ease.service.impl; + +import com.alibaba.cloud.nacos.NacosDiscoveryProperties; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.naming.NamingFactory; +import com.alibaba.nacos.api.naming.NamingService; +import com.alibaba.nacos.api.naming.pojo.Instance; +import com.qc.soft.deploy.ease.service.INacosService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +@Service +public class NacosServiceImpl implements INacosService { + + @Resource + private NacosDiscoveryProperties nacosDiscoveryProperties; + + private final static String SYNCHRONIZER_SERVICE_NAME = "deploy-ease-synchronizer-longi-%s"; + @Override + public void instances() { + try { + + NamingService namingService = NamingFactory.createNamingService(nacosDiscoveryProperties.getNacosProperties()); + List allInstances = namingService.getAllInstances(SYNCHRONIZER_SERVICE_NAME, nacosDiscoveryProperties.getGroup()); + System.out.println(allInstances); + } catch (NacosException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/ProjectServiceImpl.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/ProjectServiceImpl.java new file mode 100644 index 0000000..59e8002 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/ProjectServiceImpl.java @@ -0,0 +1,25 @@ +package com.qc.soft.deploy.ease.service.impl; + +import com.qc.soft.deploy.ease.api.response.ProjectResponse; +import com.qc.soft.deploy.ease.context.TenantContext; +import com.qc.soft.deploy.ease.convert.api.response.ProjectApiResponseConvert; +import com.qc.soft.deploy.ease.repository.IProjectRepository; +import com.qc.soft.deploy.ease.service.IProjectService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +@Service +public class ProjectServiceImpl implements IProjectService { + + + @Resource + private IProjectRepository projectRepository; + + @Override + public List list() { + String tenantCode = TenantContext.getCurrentTenant(); + return ProjectApiResponseConvert.INSTANCE.entityToResponse(projectRepository.findByTenantCode(tenantCode)); + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/UserServiceImpl.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..ec6b46a --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/service/impl/UserServiceImpl.java @@ -0,0 +1,21 @@ +package com.qc.soft.deploy.ease.service.impl; + +import com.qc.soft.deploy.ease.entity.User; +import com.qc.soft.deploy.ease.repository.IUserRepository; +import com.qc.soft.deploy.ease.service.IUserService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +@Service +public class UserServiceImpl implements IUserService { + + @Resource + private IUserRepository userRepository; + + @Override + public boolean login(String username, String password) { + User user = userRepository.findByUsernameAndPassword(username, password); + return user != null; + } +} \ No newline at end of file diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/statemachine/JenkinsJobStatemachineConfig.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/statemachine/JenkinsJobStatemachineConfig.java new file mode 100644 index 0000000..1dcceae --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/statemachine/JenkinsJobStatemachineConfig.java @@ -0,0 +1,55 @@ +package com.qc.soft.deploy.ease.statemachine; + +import com.qc.soft.deploy.ease.fegin.response.JenkinsJobResponse; +import com.qc.soft.deploy.ease.event.JenkinsJobChangeEvent; +import com.qc.soft.deploy.ease.enums.JenkinsJobStatus; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.statemachine.StateMachineContext; +import org.springframework.statemachine.StateMachinePersist; +import org.springframework.statemachine.config.EnableStateMachine; +import org.springframework.statemachine.config.StateMachineConfigurerAdapter; +import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; +import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; +import org.springframework.statemachine.persist.DefaultStateMachinePersister; +import org.springframework.statemachine.support.DefaultStateMachineContext; + +import java.util.EnumSet; + +@Configuration +@EnableStateMachine(name = "jenkinsStatemachine") +public class JenkinsJobStatemachineConfig extends StateMachineConfigurerAdapter { + + + @Override + public void configure(StateMachineStateConfigurer states) throws Exception { + states.withStates().initial(JenkinsJobStatus.WAITING_BUILD).states(EnumSet.allOf(JenkinsJobStatus.class)); + } + + + public void configure(StateMachineTransitionConfigurer transitions) throws Exception { + transitions + .withExternal().source(JenkinsJobStatus.WAITING_BUILD).target(JenkinsJobStatus.BUILDING).event(JenkinsJobChangeEvent.SUCCESS) + .and() + .withExternal().source(JenkinsJobStatus.WAITING_BUILD).target(JenkinsJobStatus.BUILDING).event(JenkinsJobChangeEvent.ABORTED) + .and() + .withExternal().source(JenkinsJobStatus.WAITING_BUILD).target(JenkinsJobStatus.BUILDING).event(JenkinsJobChangeEvent.FAILURE); + } + + @Bean + public DefaultStateMachinePersister persister() { + return new DefaultStateMachinePersister<>(new StateMachinePersist() { + @Override + public void write(StateMachineContext context, JenkinsJobResponse jenkinsJob) throws Exception { + jenkinsJob.setResult(JenkinsJobStatus.BUILD_END); + System.out.println("persister writer" + jenkinsJob.toString()); + } + + @Override + public StateMachineContext read(JenkinsJobResponse jenkinsJob) throws Exception { + System.out.println("persister read" + jenkinsJob.toString()); + return new DefaultStateMachineContext(jenkinsJob.getResult(), null, null, null); + } + }); + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/statemachine/listener/JenkinsJobStatusListenerImpl.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/statemachine/listener/JenkinsJobStatusListenerImpl.java new file mode 100644 index 0000000..aeb87af --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/statemachine/listener/JenkinsJobStatusListenerImpl.java @@ -0,0 +1,38 @@ +package com.qc.soft.deploy.ease.statemachine.listener; + +import com.qc.soft.deploy.ease.fegin.response.JenkinsJobResponse; +import com.qc.soft.deploy.ease.event.JenkinsJobChangeEvent; +import org.springframework.messaging.Message; +import org.springframework.statemachine.annotation.OnTransition; +import org.springframework.statemachine.annotation.WithStateMachine; +import org.springframework.stereotype.Component; + +@Component("jenkinsJobStatusListener") +@WithStateMachine(name = "jenkinsStatemachine") +public class JenkinsJobStatusListenerImpl { + + @OnTransition(source = "WAITING_BUILD", target = "BUILDING") + public boolean jenkinsBuildingTransition(Message message) { + JenkinsJobResponse jenkinsJobResponse = (JenkinsJobResponse) message.getHeaders().get("jenkinsJobResponse"); + jenkinsJobResponse.setResult(jenkinsJobResponse.getResult()); + System.out.println("支付,状态机反馈信息:" + message.getHeaders().toString()); + return true; + } + + @OnTransition(source = "BUILDING", target = "BUILD_END") + public boolean jenkinsBuildEndTransition(Message message) { + JenkinsJobResponse jenkinsJobResponse = (JenkinsJobResponse) message.getHeaders().get("jenkinsJobResponse"); + jenkinsJobResponse.setResult(jenkinsJobResponse.getResult()); + System.out.println("支付,状态机反馈信息:" + message.getHeaders().toString()); + return true; + } + +// @OnTransition(source = "BUILDING", target = "BUILDING") +// public boolean jenkinsBuildingTransition(Message message) { +// JenkinsJobResponse jenkinsJobResponse = (JenkinsJobResponse) message.getHeaders().get("jenkinsJobResponse"); +//// jenkinsJobResponse.setStatus(OrderStatus.WAIT_DELIVER); +// System.out.println("支付,状态机反馈信息:" + message.getHeaders().toString()); +// return true; +// } + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/BasicAuthUtils.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/BasicAuthUtils.java new file mode 100644 index 0000000..3313709 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/BasicAuthUtils.java @@ -0,0 +1,13 @@ +package com.qc.soft.deploy.ease.utils; + +import java.util.Base64; + +public class BasicAuthUtils { + + public static String encode(String userName, String password) { + String auth = userName + ":" + password; + String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes()); + return "Basic " + encodedAuth; + } + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/DateUtils.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/DateUtils.java new file mode 100644 index 0000000..f7e887c --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/DateUtils.java @@ -0,0 +1,62 @@ +package com.qc.soft.deploy.ease.utils; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.Calendar; +import java.util.Date; + +public class DateUtils { + + public static long differenceInMinutes(Date date1, Date date2) { + LocalDateTime currentLocalDateTime = LocalDateTime.ofInstant(date1.toInstant(), ZoneId.systemDefault()); + LocalDateTime pulishLocalDateTime = LocalDateTime.ofInstant(date2.toInstant(), ZoneId.systemDefault()); + Duration duration = Duration.between(currentLocalDateTime, pulishLocalDateTime); + return duration.toMinutes(); + } + + public static String formatDate(Date date, String format) { + SimpleDateFormat sdf = new SimpleDateFormat(format); + return sdf.format(date); + } + + public static boolean betweenDate(String start, String end) { + String format = "HH:mm:ss"; + String nowDate = new SimpleDateFormat(format).format(new Date()); + try { + Date beginDate = new SimpleDateFormat(format).parse(start); + Date endDate = new SimpleDateFormat(format).parse(end); + LocalDate today = LocalDate.now(); + LocalDateTime todayStart = LocalDateTime.of(today, LocalTime.MIN); + LocalDateTime todayEnd = LocalDateTime.of(today, LocalTime.MAX); + LocalDate nextDay = today.plusDays(1); + LocalDateTime nextDayStart = LocalDateTime.of(today, LocalTime.MIN); + LocalDateTime nextDayEnd = LocalDateTime.of(today, LocalTime.MAX); + long todayStartTimestamp = todayStart.toInstant(ZoneOffset.ofHours(8)).toEpochMilli(); + long todayEndTimestamp = todayEnd.toInstant(ZoneOffset.ofHours(8)).toEpochMilli(); + //先判断是第一天还是第二天 + if (todayStartTimestamp < endDate.getTime() && todayEndTimestamp > beginDate.getTime()) { + System.out.println(1); + } + boolean b = todayStartTimestamp < beginDate.getTime() && todayEndTimestamp > endDate.getTime(); + + System.out.println(1); + return false; + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + + private Date addDay(Date date, int days) { + Calendar calendar = Calendar.getInstance(); // 获取当前日期 + calendar.setTime(date); + calendar.add(Calendar.DAY_OF_YEAR, days); // 加一天 + return calendar.getTime(); + } + +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/FileUtils.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/FileUtils.java new file mode 100644 index 0000000..fb111a8 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/FileUtils.java @@ -0,0 +1,59 @@ +package com.qc.soft.deploy.ease.utils; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +import java.io.IOException; + +@Slf4j +public class FileUtils { + + private static final PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + + + public static String getJarResourcesFolderPath(String folderPath) { + try { + Resource[] resources = resolver.getResources("classpath*:/" + folderPath); + for (Resource resource : resources) { + if (!resource.exists()) { + continue; + } + return resource.getURI().getRawPath(); + } + } catch (IOException e) { + log.error("Resource file not found, folderPath:{}", folderPath); + } + throw new NullPointerException("Folder path not found"); + } + + public static String getJarResourcesFilePath(String path, String fileName) { + try { + Resource[] resources = resolver.getResources("classpath*:/" + path + "/" + fileName); + for (Resource resource : resources) { + if (!resource.isReadable()) { + continue; + } + return resource.getURI().getRawPath(); + } + } catch (IOException e) { + log.error("Resource file not found, path:{}, fileName:{}", path, fileName); + } + throw new NullPointerException("Resource file not found"); + } + + public static Resource getJarFileResources(String path) { + try { + Resource[] resources = resolver.getResources("classpath*:/" + path); + for (Resource resource : resources) { + if (!resource.isReadable()) { + continue; + } + return resource; + } + } catch (IOException e) { + log.error("Resource file not found, path:{}", path); + } + throw new NullPointerException("Resource file not found"); + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/HttpUtils.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/HttpUtils.java new file mode 100644 index 0000000..d346c91 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/HttpUtils.java @@ -0,0 +1,260 @@ +package com.qc.soft.deploy.ease.utils; + +import cn.hutool.core.map.MapUtil; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.hc.client5.http.classic.methods.HttpDelete; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.apache.logging.log4j.util.Strings; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.Map; +import java.util.Optional; + +@Slf4j +public class HttpUtils { + + public static final int fileSize = 10 * 1024; + + public static T get(String url, Map header, Class cls) { + CloseableHttpClient httpclient = HttpClients.createDefault(); + HttpGet get = new HttpGet(url); + CloseableHttpResponse response = null; + try { + if (!MapUtil.isEmpty(header)) { + header.forEach(get::setHeader); + } + response = httpclient.execute(get); + HttpEntity entity = response.getEntity(); + String result = EntityUtils.toString(entity); + EntityUtils.consume(entity); + return JSON.parseObject(result, cls); + } catch (Exception e) { + log.error("http get error, url:{}", url, e); + } finally { + try { + if (response != null) { + response.close(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return null; + } + + public static Map get(String url, Map header) { + CloseableHttpClient httpclient = HttpClients.createDefault(); + HttpGet get = new HttpGet(url); + CloseableHttpResponse response = null; + try { + if (!MapUtil.isEmpty(header)) { + header.forEach(get::setHeader); + } + response = httpclient.execute(get); + HttpEntity entity = response.getEntity(); + String result = EntityUtils.toString(entity); + EntityUtils.consume(entity); + return JSON.parseObject(result, Map.class); + } catch (Exception e) { + log.error("http get error, url:{}", url); + } finally { + try { + if (response != null) { + response.close(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return new HashMap<>(); + } + + + public static void delete(String url, Map header) { + CloseableHttpClient httpclient = HttpClients.createDefault(); + HttpDelete delete = new HttpDelete(url); + CloseableHttpResponse response = null; + try { + if (!MapUtil.isEmpty(header)) { + header.forEach(delete::setHeader); + } + response = httpclient.execute(delete); + log.info("Remove nexus url:{} success", url); + } catch (Exception e) { + log.error("http delete error, url:{}", url, e); + } finally { + try { + if (response != null) { + response.close(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + public static Map post(String url, IdentityHashMap header) { + CloseableHttpClient httpclient = HttpClients.createDefault(); + HttpPost post = new HttpPost(url); + CloseableHttpResponse response = null; + Map result = new HashMap<>(); + try { + if (!MapUtil.isEmpty(header)) { + header.forEach(post::setHeader); + } + response = httpclient.execute(post); + HttpEntity entity = response.getEntity(); + result.put("code", response.getCode()); + result.put("message", EntityUtils.toString(response.getEntity())); + EntityUtils.consume(entity); + log.info("Http client post success, response:{}", response); + return result; + } catch (Exception e) { + log.error("http post error, url:{}", url, e); + } finally { + try { + if (response != null) { + response.close(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + result.put("code", 0); + return result; + } + + public static T cookieGet(String url, Map header, Class cls) { + CloseableHttpClient httpclient = HttpClients.createDefault(); + HttpGet get = new HttpGet(url); + CloseableHttpResponse response = null; + try { + if (!MapUtil.isEmpty(header)) { + header.forEach(get::setHeader); + } + response = httpclient.execute(get); + HttpEntity entity = response.getEntity(); + String result = EntityUtils.toString(entity); + Optional
cookieOptional = Arrays.stream(response.getHeaders()).filter(v -> v.getName().equals("Set-Cookie")).findFirst(); + if (cookieOptional.isPresent()) { + Header cookie = cookieOptional.get(); + String cookieValue = cookie.getValue().substring(0, cookie.getValue().indexOf(";")); + JSONObject tempObject = JSON.parseObject(result); + tempObject.put("cookie", cookieValue); + result = JSON.toJSONString(tempObject); + } + EntityUtils.consume(entity); + log.info("http cookie get result:{}", result); + return JSON.parseObject(result, cls); + } catch (Exception e) { + log.error("http get error, url:{}", url, e); + } finally { + try { + if (response != null) { + response.close(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return null; + } + + public static String downloadFile(String url, Map header, String downloadBuildFailedFilePath, String fileName) { + String fullFilePath = downloadBuildFailedFilePath + File.separator + fileName; + CloseableHttpClient httpclient = HttpClients.createDefault(); + HttpGet get = new HttpGet(url); + CloseableHttpResponse response = null; + try { + File directory = new File(downloadBuildFailedFilePath); + if (!directory.exists()) { + directory.mkdirs(); + } + if (!directory.isDirectory()) { + return null; + } + if (!MapUtil.isEmpty(header)) { + header.forEach(get::setHeader); + } + response = httpclient.execute(get); + HttpEntity entity = response.getEntity(); + InputStream is = entity.getContent(); + File file = new File(fullFilePath); + if (file.exists()) { + log.info("Download file exists,will be deleted, fileName:{}", fileName); + file.delete(); + } + file.createNewFile(); + FileOutputStream os = new FileOutputStream(file); + byte[] buffer = new byte[fileSize]; + int ch = 0; + while ((ch = is.read(buffer)) != -1) { + os.write(buffer, 0, ch); + } + is.close(); + os.flush(); + os.close(); + EntityUtils.consume(entity); + log.info("Download file success, url:{}, filePath:{}", url, fullFilePath); + return fullFilePath; + } catch (Exception e) { + log.error("Download file failed, url:{}", url); + } finally { + try { + if (response != null) { + response.close(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return null; + } + + public static T uploadFile(String url, String filePath, Class cls) { + CloseableHttpResponse response = null; + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + HttpPost httpPost = new HttpPost(url); + File file = new File(filePath); + if (!file.exists()) { + log.error("Upload file not exists, filePath:{}", filePath); + return null; + } + HttpEntity fileEntity = MultipartEntityBuilder.create().addBinaryBody("file", file).build(); + httpPost.setEntity(fileEntity); + response = httpClient.execute(httpPost); + HttpEntity entity = response.getEntity(); + String content = EntityUtils.toString(entity); + EntityUtils.consume(entity); + return JSON.parseObject(content, cls); + } catch (Exception e) { + log.error("Upload file failed, url:{}, filePath:{}, response:{}", url, filePath, JSON.toJSONString(response)); + } finally { + if (response != null) { + try { + response.close(); + } catch (IOException e) { + log.error("Upload file close response failed, url:{}, filePath:{}", url, filePath); + } + } + } + return null; + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/K8sClientUtils.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/K8sClientUtils.java new file mode 100644 index 0000000..cf5a582 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/K8sClientUtils.java @@ -0,0 +1,263 @@ +package com.qc.soft.deploy.ease.utils; + +import io.kubernetes.client.openapi.ApiClient; +import io.kubernetes.client.openapi.ApiException; +import io.kubernetes.client.openapi.apis.AppsV1Api; +import io.kubernetes.client.openapi.apis.CoreV1Api; +import io.kubernetes.client.openapi.models.V1DeploymentList; +import io.kubernetes.client.openapi.models.V1EndpointsList; +import io.kubernetes.client.openapi.models.V1NamespaceList; +import io.kubernetes.client.openapi.models.V1PodList; +import io.kubernetes.client.openapi.models.V1Scale; +import io.kubernetes.client.util.ClientBuilder; +import io.kubernetes.client.util.KubeConfig; +import lombok.extern.slf4j.Slf4j; + +import java.io.FileReader; +import java.io.IOException; + +@Slf4j +public class K8sClientUtils { + + private ApiClient apiClient; + + + /** + * 构建集群POD内通过SA访问的客户端 + * loading the in-cluster config2, including: + * 1. service-account CA + * 2. service-account bearer-token + * 3. service-account namespace + * 4. master endpoints(ip, port) from pre-set environment variables + */ + public K8sClientUtils() { + try { + this.apiClient = ClientBuilder.cluster().build(); + } catch (IOException e) { + log.error("构建K8s-Client异常", e); + throw new RuntimeException("构建K8s-Client异常"); + } + } + + + /** + * 构建集群外通过UA访问的客户端 + * loading the out-of-cluster config2, a kubeconfig from file-system + * + * @param kubeConfigPath kube连接配置文件 + */ + public K8sClientUtils(String kubeConfigPath) { + try { + this.apiClient = ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath))).build(); + } catch (IOException e) { + log.error("读取kubeConfigPath异常", e); + throw new RuntimeException("读取kubeConfigPath异常"); + } catch (Exception e) { + log.error("构建K8s-Client异常", e); + throw new RuntimeException("构建K8s-Client异常"); + } + } + + + /** + * 获取所有的Pod + * + * @return podList + */ + public V1PodList getAllPodList() { + // new a CoreV1Api + CoreV1Api api = new CoreV1Api(apiClient); + // invokes the CoreV1Api client + try { + V1PodList list = api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null, null, null); + return list; + } catch (ApiException e) { + log.error("获取podlist异常:" + e.getResponseBody(), e); + } + return null; + } + + public V1NamespaceList getAllNamespaceList() { + // new a CoreV1Api + CoreV1Api api = new CoreV1Api(apiClient); + // invokes the CoreV1Api client + try { + return api.listNamespace(null, null, null, null, null, null, null, null, null, null, null); + } catch (ApiException e) { + log.error("获取podlist异常:" + e.getResponseBody(), e); + } + return null; + } + + public V1DeploymentList getDeploymentList(String namespace) { + try { + AppsV1Api api = new AppsV1Api(apiClient); + return api.listNamespacedDeployment(namespace, null, null, null, null, null, null, null, null, null, null, null); + } catch (ApiException e) { + throw new RuntimeException(e); + } + } + + public V1EndpointsList getEndpointsList() { + // new a CoreV1Api + CoreV1Api api = new CoreV1Api(apiClient); + // invokes the CoreV1Api client + try { + return api.listEndpointsForAllNamespaces(null, null, null, null, null, null, null, null, null, null, null); + } catch (ApiException e) { + log.error("获取podlist异常:" + e.getResponseBody(), e); + } + return null; + } + + public V1Scale readNamespacedDeploymentScale(String namespace, String name) { + try { + AppsV1Api api = new AppsV1Api(apiClient); + return api.readNamespacedDeploymentScale(name, namespace, null); + } catch (ApiException e) { + throw new RuntimeException(e); + } + } + + public V1Scale replaceNamespacedDeploymentScale(String appName, String namespace, V1Scale v1Scale){ + try { + AppsV1Api api = new AppsV1Api(apiClient); + return api.replaceNamespacedDeploymentScale(appName, namespace, v1Scale, null, null, null, null); + } catch (ApiException e) { + throw new RuntimeException(e); + } + } + + + /** + * 创建k8s service + * + * @param namespace 命名空间 + * @param serviceName 服务名称 + * @param port 服务端口号(和目标pod的端口号一致) + * @param selector pod标签选择器 + * @return 创建成功的service对象 + */ +// public V1Service createService(String namespace, String serviceName, Integer port, Map selector) { +// //构建service的yaml对象 +// V1Service +// .withNewMetadata() +// .withName(serviceName) +// .endMetadata() +// .withNewSpec() +// .addNewPort() +// .withProtocol("TCP") +// .withPort(port) +// .withTargetPort(new IntOrString(port)) +// .endPort() +// .withSelector(selector) +// .endSpec() +// .build(); +// +// +// // Deployment and StatefulSet is defined in apps/v1, so you should use AppsV1Api instead of CoreV1API +// CoreV1Api api = new CoreV1Api(apiClient); +// V1Service v1Service = null; +// try { +// v1Service = api.createNamespacedService(namespace, svc, null, null, null); +// } catch (ApiException e) { +// log.error("创建service异常:" + e.getResponseBody(), e); +// } catch (Exception e) { +// log.error("创建service系统异常:", e); +// } +// return v1Service; +// } + + + /** + * 创建k8s V1Ingress + * + * @param namespace 命名空间 + * @param ingressName ingress名称 + * @param annotations ingress注解 + * @param path 匹配的路径 + * @param serviceName 路由到的服务名称 + * @param servicePort 路由到的服务端口 + * @return 创建成功的ingress对象 + */ +// public V1Ingress createV1Ingress(String namespace, String ingressName, Map annotations, String path, +// String serviceName, Integer servicePort) { +// //构建ingress的yaml对象 +// V1Ingress ingress = new V1IngressBuilder() +// .withNewMetadata() +// .withName(ingressName) +// .withAnnotations(annotations) +// .endMetadata() +// .withNewSpec() +// .addNewRule() +// .withHttp(new V1HTTPIngressRuleValueBuilder().addToPaths(new V1HTTPIngressPathBuilder() +// .withPath(path) +// .withPathType("Prefix") +// .withBackend(new V1IngressBackendBuilder() +// .withService(new V1IngressServiceBackendBuilder() +// .withName(serviceName) +// .withPort(new V1ServiceBackendPortBuilder() +// .withNumber(servicePort).build()).build()).build()).build()).build()) +// .endRule() +// .endSpec() +// .build(); +// +// +// //调用对应的API执行创建ingress的操作 +// NetworkingV1Api api = new NetworkingV1Api(apiClient); +// V1Ingress v1Ingress = null; +// try { +// v1Ingress = api.createNamespacedIngress(namespace, ingress, null, null, null); +// } catch (ApiException e) { +// log.error("创建ingress异常:" + e.getResponseBody(), e); +// } catch (Exception e) { +// log.error("创建ingress系统异常:", e); +// } +// return v1Ingress; +// } + + + /** + * 创建k8s ExtensionIngress + * + * @param namespace 命名空间 + * @param ingressName ingress名称 + * @param annotations ingress注解 + * @param path 匹配的路径 + * @param serviceName 路由到的服务名称 + * @param servicePort 路由到的服务端口 + * @return 创建成功的ingress对象 + */ +// public ExtensionsV1beta1Ingress createExtensionIngress(String namespace, String ingressName, Map annotations, String path, +// String serviceName, Integer servicePort) { +// //构建ingress的yaml对象 +// ExtensionsV1beta1Ingress ingress = new ExtensionsV1beta1IngressBuilder() +// .withNewMetadata() +// .withName(ingressName) +// .withAnnotations(annotations) +// .endMetadata() +// .withNewSpec() +// .addNewRule() +// .withHttp(new ExtensionsV1beta1HTTPIngressRuleValueBuilder().addToPaths(new ExtensionsV1beta1HTTPIngressPathBuilder() +// .withPath(path) +// .withBackend(new ExtensionsV1beta1IngressBackendBuilder() +// .withServiceName(serviceName) +// .withServicePort(new IntOrString(servicePort)).build()).build()).build()) +// .endRule() +// .endSpec() +// .build(); +// +// +// //调用对应的API执行创建ingress的操作 +// ExtensionsV1beta1Api api = new ExtensionsV1beta1Api(apiClient); +// ExtensionsV1beta1Ingress extensionsV1beta1Ingress = null; +// try { +// extensionsV1beta1Ingress = api.createNamespacedIngress(namespace, ingress, null, null, null); +// } catch (ApiException e) { +// log.error("创建ingress异常:" + e.getResponseBody(), e); +// } catch (Exception e) { +// log.error("创建ingress系统异常:", e); +// } +// return extensionsV1beta1Ingress; +// } +} \ No newline at end of file diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/MapUtils.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/MapUtils.java new file mode 100644 index 0000000..10017fe --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/MapUtils.java @@ -0,0 +1,22 @@ +package com.qc.soft.deploy.ease.utils; + +import java.util.Map; +import java.util.HashMap; +import java.lang.reflect.Field; + +public class MapUtils { + public static Map toMap(Object object) { + try { + Map map = new HashMap<>(); + Class clazz = object.getClass(); + for (Field field : clazz.getDeclaredFields()) { + field.setAccessible(true); + Object value = field.get(object) == null ? null : field.get(object).toString(); + map.put(field.getName(), value); + } + return map; + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/StrUtils.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/StrUtils.java new file mode 100644 index 0000000..0fc0ab9 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/StrUtils.java @@ -0,0 +1,9 @@ +package com.qc.soft.deploy.ease.utils; + +public class StrUtils { + + public static boolean containsChineseCharacters(String str) { + String regex = "[\\u4e00-\\u9fa5]"; + return str.matches(".*" + regex + ".*"); + } +} diff --git a/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/TemplateParamsBuildUtils.java b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/TemplateParamsBuildUtils.java new file mode 100644 index 0000000..138e163 --- /dev/null +++ b/deploy-ease-core/src/main/java/com/qc/soft/deploy/ease/utils/TemplateParamsBuildUtils.java @@ -0,0 +1,14 @@ +package com.qc.soft.deploy.ease.utils; + +import java.util.HashMap; +import java.util.Map; + +public class TemplateParamsBuildUtils { + + public static Map build(Object templateParams) { + Map params = new HashMap<>(); + params.put("templateParams", templateParams); + return params; + } + +} diff --git a/deploy-ease-core/src/main/resources/application.yml b/deploy-ease-core/src/main/resources/application.yml new file mode 100644 index 0000000..e69de29 diff --git a/deploy-ease-core/src/main/resources/bootstrap.yml b/deploy-ease-core/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..9ad47f6 --- /dev/null +++ b/deploy-ease-core/src/main/resources/bootstrap.yml @@ -0,0 +1,29 @@ +spring: + cloud: + nacos: + server-addr: ${NACOS_CONFIG_SERVER:192.168.105.1:8848} + discovery: + group: ${DEPLOY_ENV} + namespace: ${DEPLOY_ENV} + username: ${NACOS_USER} + password: ${NACOS_PWD} + enabled: true + config: + group: ${DEPLOY_ENV} + namespace: ${DEPLOY_ENV} + username: ${NACOS_USER} + password: ${NACOS_PWD} + extension-configs[0]: + data-id: common.yml + group: common + refresh: false + extension-configs[1]: + data-id: deploy-ease-core.yml + group: business + refresh: false + config: + override-none: false + allow-override: true + override-system-properties: false + main: + allow-bean-definition-overriding: true \ No newline at end of file diff --git a/deploy-ease-core/src/main/resources/kube/config b/deploy-ease-core/src/main/resources/kube/config new file mode 100644 index 0000000..ecd6768 --- /dev/null +++ b/deploy-ease-core/src/main/resources/kube/config @@ -0,0 +1,19 @@ +apiVersion: v1 +clusters: +- cluster: + server: https://10.201.127.46:6443 + certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQ2akNDQXRLZ0F3SUJBZ0lDRHhzd0RRWUpLb1pJaHZjTkFRRUxCUUF3YWpFcU1DZ0dBMVVFQ2hNaFl6TTQKTUdVNFpHWm1ORFZoTXpRME1HSTRaamhrWm1SaE1qSTNaV05qWm1FMk1SQXdEZ1lEVlFRTEV3ZGtaV1poZFd4MApNU293S0FZRFZRUURFeUZqTXpnd1pUaGtabVkwTldFek5EUXdZamhtT0dSbVpHRXlNamRsWTJObVlUWXdIaGNOCk1qTXdOVEU1TURJek16QXdXaGNOTkRNd05URTBNREl6T0RVMldqQnFNU293S0FZRFZRUUtFeUZqTXpnd1pUaGsKWm1ZME5XRXpORFF3WWpobU9HUm1aR0V5TWpkbFkyTm1ZVFl4RURBT0JnTlZCQXNUQjJSbFptRjFiSFF4S2pBbwpCZ05WQkFNVElXTXpPREJsT0dSbVpqUTFZVE0wTkRCaU9HWTRaR1prWVRJeU4yVmpZMlpoTmpDQ0FTSXdEUVlKCktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU9FTmlzRWtSblNsSDhtRDJFUkFoS2ZWdWkyN0hTUFMKQTViT2lKdDZWNnRxVHhmTWRwR0RIMTVCbFlKL1laMFZyeERGUjVyMkJBREVkcXdsVG10NWozTFVIcXN6MnRoKwp2RzFrY0UyMmhUdFNtR05KQjhjbzA2YWNxaHV6YlhMbEZMQlc5eURNVnNENWc4RFBvZzh4QnFXZGg2NVRqeGx5ClkwZjJLeUVBS2V6YUFzc3RHV0swSDIvU2EvenZlb25GNnBJREtKcHh6SjZOSTZ5dUdlTk5hRkMwYXNTTVRJSjIKZHFGT01uWFpFdmZqTVlhU2QxWk5FdFUweUxkYzEyRDlVRmJUamxMSEZxcG9rYit2a202T0tGNi9iOUhCN0xXNgpsZFZMTFdHUkhrbS81Vmg5NTVnOVJFUUNVYVN4THpiSkwrVzlBU3puWWJlcnc0RUtpWWxjSUkwQ0F3RUFBYU9CCm1UQ0JsakFPQmdOVkhROEJBZjhFQkFNQ0Fxd3dEd1lEVlIwVEFRSC9CQVV3QXdFQi96QThCZ2dyQmdFRkJRY0IKQVFRd01DNHdMQVlJS3dZQkJRVUhNQUdHSUdoMGRIQTZMeTlqWlhKMGN5NWhZM011WVd4cGVYVnVMbU52YlM5dgpZM053TURVR0ExVWRId1F1TUN3d0txQW9vQ2FHSkdoMGRIQTZMeTlqWlhKMGN5NWhZM011WVd4cGVYVnVMbU52CmJTOXliMjkwTG1OeWJEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTVJOVjF0K1F6TUo5ZDlkekNDZzVULzkKQnI2T2piQVFSeHhodkVDV0JmODVOeEZUWDNYRmMzbVpkcytNeWFRRERhcUhjbzRmNGZHZ3hKRjVldmZ6cWlTZApVUVZYYktVRlFGVVgvZklnNHlDM290NWxSakw3QjR1VDJyYnI0dEhNYkUySy92ZGVUTXVBNUo0Z0pHV0IvRzBqCmtWSldYYmNJVVFDbGZzMUVQZDQ5b2VDdzBianRXOG9HSkt3S2NYYTloK1U1QytCVktTN21LNm9veUFqQ0kzRE4KNW9NS0VCdlM0aElqdFBTYjJlOE5HOWNCaGd2TXRTU2pITGRXaHpINUlrZ013dWJTUldMOEJqRDd1SzVFWmJteQpOMzNMSGFldEFIMTZQM0IvT0F0WGJWcmk2aWM2Q2lLbXBseTdhWnlGcitEeW92b2NpdjNxNFRtZVVwaHNRQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + name: kubernetes +contexts: +- context: + cluster: kubernetes + user: "298101684398995518" + name: 298101684398995518-c380e8dff45a3440b8f8dfda227eccfa6 +current-context: 298101684398995518-c380e8dff45a3440b8f8dfda227eccfa6 +kind: Config +preferences: {} +users: +- name: "298101684398995518" + user: + client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQwVENDQXJtZ0F3SUJBZ0lDRDNrd0RRWUpLb1pJaHZjTkFRRUxCUUF3YWpFcU1DZ0dBMVVFQ2hNaFl6TTQKTUdVNFpHWm1ORFZoTXpRME1HSTRaamhrWm1SaE1qSTNaV05qWm1FMk1SQXdEZ1lEVlFRTEV3ZGtaV1poZFd4MApNU293S0FZRFZRUURFeUZqTXpnd1pUaGtabVkwTldFek5EUXdZamhtT0dSbVpHRXlNamRsWTJObVlUWXdIaGNOCk1qTXdOVEkwTURZME16QXdXaGNOTWpZd05USXpNRFkwT0RJMVdqQS9NUlV3RXdZRFZRUUtFd3h6ZVhOMFpXMDYKZFhObGNuTXhDVEFIQmdOVkJBc1RBREViTUJrR0ExVUVBeE1TTWprNE1UQXhOamcwTXprNE9UazFOVEU0TUlJQgpJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBcU85R3YyRWJsUWt5ZFJmR2FTK0NabndVClMyZXFRaUJTL1JxRlVyRTlxR2dsYWtMS0g3aGZmMjdXZXppVTNzQWJQT2RLUEtSQWpSZy9jcnc4WTRXVTV0clAKWUZIb2IwTnoyMjVWcFl1YUlGWnhIVzRLTTlqSzM1Q0dQNmJDK3FCOXBGV0JxcDl1bkJKS0RKbFBSUUJLUDVucQpRRmx6aG0wQ2E1a2haNXovNWczeitpRlVWck1zazlJWGVDc2dFeE5kMjE1ckRHUUhKRVhkSlB2T2RpVmlJTUF4CmdtNmI5SzRHVUZnRXVWa0tROU1lNTVQQ2NuMnVYbnFZRVA1ckZZSU81SUFtVFlhV016NUJCZnZDTDZiRndocEIKMVR5UHVNWjRkWXZjZkNXVmNFQWpuZDdmMEN0aHdEL2FiYTNsT1JGbTB4UFVLSzRxY1FTM1kxYWhHaURBc1FJRApBUUFCbzRHck1JR29NQTRHQTFVZER3RUIvd1FFQXdJSGdEQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBakFNCkJnTlZIUk1CQWY4RUFqQUFNRHdHQ0NzR0FRVUZCd0VCQkRBd0xqQXNCZ2dyQmdFRkJRY3dBWVlnYUhSMGNEb3YKTDJObGNuUnpMbUZqY3k1aGJHbDVkVzR1WTI5dEwyOWpjM0F3TlFZRFZSMGZCQzR3TERBcW9DaWdKb1lrYUhSMApjRG92TDJObGNuUnpMbUZqY3k1aGJHbDVkVzR1WTI5dEwzSnZiM1F1WTNKc01BMEdDU3FHU0liM0RRRUJDd1VBCkE0SUJBUUNJV0VSZzFUU3IrUEg2bHh1enhTd2lEWHlGbWoxdXJZays1clhKUVZQSnVmYlF5T2ZremRIUThGWWkKSGQ5bUQxQVVKKzNGQWh1Yyt0aUFzaDZXbW5oK0s3Q1k2K0xJRWZNYm5hWlJzckQ1R1M0YjJMYWJRUE5QWXVXQQoyNjVIWWNwV1BOUE5ENFNWV1VWbGRvNi9TZmdoY2RyZG1jUERMcG56SWUzaTdKQ0NYWEJmbDNjZTdWUXU0Vk53CkVzVGQ0ZURGYTdoTlBWZ25yanVmZjBCNzZjU1hySGJkblEzdmFFcnBGUXh4elNCSnFnQTUwY0gwT21xMXRHUWEKWlZlbzBjWkRpS28rTmdnVm9xVUNtanpab0JZZjRkUmVnQXUzZ3g5eEhqVGRpY0hrRTkrdmNmS2xtRy9xZ01oRQpCbzl5WFVtc0IyUTN1b0UrRkxjZ1VTTmRodXk2Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBcU85R3YyRWJsUWt5ZFJmR2FTK0NabndVUzJlcVFpQlMvUnFGVXJFOXFHZ2xha0xLCkg3aGZmMjdXZXppVTNzQWJQT2RLUEtSQWpSZy9jcnc4WTRXVTV0clBZRkhvYjBOejIyNVZwWXVhSUZaeEhXNEsKTTlqSzM1Q0dQNmJDK3FCOXBGV0JxcDl1bkJKS0RKbFBSUUJLUDVucVFGbHpobTBDYTVraFo1ei81ZzN6K2lGVQpWck1zazlJWGVDc2dFeE5kMjE1ckRHUUhKRVhkSlB2T2RpVmlJTUF4Z202YjlLNEdVRmdFdVZrS1E5TWU1NVBDCmNuMnVYbnFZRVA1ckZZSU81SUFtVFlhV016NUJCZnZDTDZiRndocEIxVHlQdU1aNGRZdmNmQ1dWY0VBam5kN2YKMEN0aHdEL2FiYTNsT1JGbTB4UFVLSzRxY1FTM1kxYWhHaURBc1FJREFRQUJBb0lCQUFoL3FSNTlveWFYUk51UgpLNkVsQzdsZUtxTTBmdU0rdnc0T3BJQnBmRUdabzdBNTFmTk1ramxWK1NKUDBXVjNZcWRvdDFwZnBRTzBJWlVECkZVS29lTG80YmRCWnJvalNhdVN5STBybHdBWTZjd3hZK2RocjRxRG1vMnBXV0Y3RmJpeXpSSWV4NTUyZ2FldEMKVnpPUWRTdkg4WG4xUmhPUUxsdjlZeW5VUXlkdW5WZndtY0NsM2ZsVjZqY3BoaHJYNmgrNzZjOVRGQXRpUDFlWAprNXNsOVUrZzl5N3ZlbzFEY2s4eXBENnZSMlF1MldKWlZLRDQycG52Y0YrUzlEYlA4UWRFLytlZ0Y5OEhSRitmClBoMHNaa2ErQ3R5dHVOWnVXaW5hN3hBRnI0cDRndXZ2U1RXVm02enpHU3ZhSkJZRC9CSjVQVThieGQ2NGRMNlAKVXVka0d2VUNnWUVBMEc5V09WbHJ5U0ZrMnhhOXk3T0RMSm13QXlJL0J3VkF3c2VUd0VOUjIxT1MxdmV1ajFYWgozc0p3emlubEpBTCt4dm9Sem0xbWljRnlDMUhqM1VZaytPck1IM1RyOW9sWnZ0VFhSbjNZeWtjUEl3Ny9acXlsCkV1dzhrZWZBSVJFZlV5YVlCUzNvOG5DUUtyVDdyWEV2Z0lOWUJGWVFCL0dpSW93Z1NUZ2RMSnNDZ1lFQXozeGIKQWd1c1I4b0ZPWUJ0bnBNZWNXdHp2WjRqTDVyWDIwQTN2bm9qc3hlS2QxdEJ3aTEzRnZjeUI2TDZuQ1NNS24xQQp6MFVJbENGREVqZzA1SHRDc3MzOGRRNHVIUG16eXdob2NiazRBeWdYcHVqNnA2MDdYS3NuN2xiWG9PMnV6SXlKCkp5QWpid2ozejN1UWNsQmhFOXF5UnpjOXN4MUszUGtQajg5MHJxTUNnWUJwSzRScU00QjdYK292MGUyNlZyMmQKUjM3VVZmZFBaNHNodk9vRVhQTjBvMXE0TlFsVE1aSlpIK3NqVzJoUEgyUEdxbTlKcFZIVHVGUCsramJyYzNVOApVOXpqRW0vdFdhaDY3WkloODJYcnlxY01uWWlwR2Z2QTdJb3paS2hCQnc2ek9nb0Nzd09UTU5ETmU3eHg2Mlo0CmhjMW5nclZjRE1RdWdsM1lGQVJFZVFLQmdHNTJhMUZVZTUwZ3ZkVldQWVllRnlnVkorSjhyWWpyckI0TE8ySksKVG5WTGhDbDFTVFlpMUhOQ21iMGRGTVZLWStFL0crRDloTXF3UnJBTmdvTmQ2QzJmb3RlQy9DUHJBTUNJTW1yUgpURFBLQllXVUpkWmRVT3hPSncwcDZOVEJsYjFLMkw0ZXl4NlRMTE9tdWtsUjU4MFZNckxkZ3hpMzhLSmlhdG1LCmZqbDNBb0dBYTlMVDZtTm9qejc1OVB2eCtwNEJoemhRakpSQm1ITUNLdUNoTnFYTkxwTmx3MXJscHluUDFjcXgKNlhjL09iUVdrSHJEVUpUb2VyamZPS05HTkl4cUdOcDdHMm5GVWorT290UElkVEpKU1ErQVNtWU5HSlJWVUJIWQpWYmNLWENSZE1yQTNoNFB2RUl2V0M4d21iZEtaYnBLYUI0NzdVeEF3S2gxYmpEcnU1OWs9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== \ No newline at end of file diff --git a/deploy-ease-core/src/main/resources/kube/config2 b/deploy-ease-core/src/main/resources/kube/config2 new file mode 100644 index 0000000..9794c48 --- /dev/null +++ b/deploy-ease-core/src/main/resources/kube/config2 @@ -0,0 +1,19 @@ +apiVersion: v1 +clusters: +- cluster: + server: https://10.201.11.56:6443 + certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQ2akNDQXRLZ0F3SUJBZ0lDRU80d0RRWUpLb1pJaHZjTkFRRUxCUUF3YWpFcU1DZ0dBMVVFQ2hNaFkyRmwKWXpFeU56UmtZV0kwTURSaU9EUmlOR1ZoTVRVNE9HWmtNakEwWVdNMU1SQXdEZ1lEVlFRTEV3ZGtaV1poZFd4MApNU293S0FZRFZRUURFeUZqWVdWak1USTNOR1JoWWpRd05HSTROR0kwWldFeE5UZzRabVF5TURSaFl6VXdIaGNOCk1qTXdOekkyTURJeU9EQXdXaGNOTkRNd056SXhNREl6TXpVMFdqQnFNU293S0FZRFZRUUtFeUZqWVdWak1USTMKTkdSaFlqUXdOR0k0TkdJMFpXRXhOVGc0Wm1ReU1EUmhZelV4RURBT0JnTlZCQXNUQjJSbFptRjFiSFF4S2pBbwpCZ05WQkFNVElXTmhaV014TWpjMFpHRmlOREEwWWpnMFlqUmxZVEUxT0RobVpESXdOR0ZqTlRDQ0FTSXdEUVlKCktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUt4cHVSc3FnMVhTaUZTVk51bzhCRG44Qml0WW5VMzAKWU16RHlaQXhUSWFwSmpxNXI4MHAzM0k3L0lNaFFPbWtNRXJsMDVMZmpXNlFxTFlDUFVtck1LL2RyaDBMd1hRZgpJeUQ0TmpzYm92cnFpMU9ZeXZCUzZFZlg2RWh2am1ZN2d3TnRQbUFqY1IweEd5ZHlqdmtlQ1M3SXJKVDlzSGdOClFrbGJxRStqUFU2NWpzVEd5cnNzZUo3aXBkSXg4NE94VURNWFBsOUN1NHlzWDc0NU4zYkxEaTJFbWJMbWNqYXkKeElEaGp2K2RoL0psQ1lNQnRScWpTWFpuY0kvdHc5OUNmUmU0aDlMNWNjd0pQd3pjdFhPM2FTSFN3bC8wZzZlQQovK2FScEQvNTlleTdZbWNHUDliN3piNitIUUJDUytmekZKUU5WRFJOTUpKUkxGcjFaNFhBbVJFQ0F3RUFBYU9CCm1UQ0JsakFPQmdOVkhROEJBZjhFQkFNQ0Fxd3dEd1lEVlIwVEFRSC9CQVV3QXdFQi96QThCZ2dyQmdFRkJRY0IKQVFRd01DNHdMQVlJS3dZQkJRVUhNQUdHSUdoMGRIQTZMeTlqWlhKMGN5NWhZM011WVd4cGVYVnVMbU52YlM5dgpZM053TURVR0ExVWRId1F1TUN3d0txQW9vQ2FHSkdoMGRIQTZMeTlqWlhKMGN5NWhZM011WVd4cGVYVnVMbU52CmJTOXliMjkwTG1OeWJEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFOSkhCaW9oVjNuekI1SHp5cW1lS3ZXUzAKOWtXVzE4UVBMQkJaMWVERHQ5RjFtSXd5ZjB0RUVJQ2h0eXMxQ1BuSjN6ejZXRkt4aENvZTlINW4yOGZQckwraQo3SHUyN1RGWUs1WGlVK1dYaDR6QWpxdUxNNWZ0V0YyU3JjNHdxeERkZnEyeXRPNHA4UEpHSUVpRTc3WnJpU3BCCkw4OENpbU5WZ1VuVUZJSVE0OUt3SDZCbVVUV3ljV0JvSHBKK3VJT0pCQ205MHc5V2d4aDQrVGZqR09NcDVaM2oKS0pRR21pWVN3cklKMVhpeHB0Um5rRXF2eGljcWNPNlhWNjRIUjJuekpDMlpqT002UWx3ZTJTbnphaS9TQjN0SwpyU3krdnJKSmI5emtuQWpQSmovUURxeDVlVldjTTVtc0xGSVBQc3F2enNVM0Y1dGIvVllHOXA1NTRLcXEyUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + name: kubernetes +contexts: +- context: + cluster: kubernetes + user: "282060690334189826" + name: 282060690334189826-caec1274dab404b84b4ea1588fd204ac5 +current-context: 282060690334189826-caec1274dab404b84b4ea1588fd204ac5 +kind: Config +preferences: {} +users: +- name: "282060690334189826" + user: + client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQwVENDQXJtZ0F3SUJBZ0lDRVBBd0RRWUpLb1pJaHZjTkFRRUxCUUF3YWpFcU1DZ0dBMVVFQ2hNaFkyRmwKWXpFeU56UmtZV0kwTURSaU9EUmlOR1ZoTVRVNE9HWmtNakEwWVdNMU1SQXdEZ1lEVlFRTEV3ZGtaV1poZFd4MApNU293S0FZRFZRUURFeUZqWVdWak1USTNOR1JoWWpRd05HSTROR0kwWldFeE5UZzRabVF5TURSaFl6VXdIaGNOCk1qTXdOekkzTURZeE5UQXdXaGNOTWpZd056STJNRFl5TURFNVdqQS9NUlV3RXdZRFZRUUtFd3h6ZVhOMFpXMDYKZFhObGNuTXhDVEFIQmdOVkJBc1RBREViTUJrR0ExVUVBeE1TTWpneU1EWXdOamt3TXpNME1UZzVPREkyTUlJQgpJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBcEo3b20wTk1LeFpOUkU1RDVuWXQwcGNWCjdTL3BmNG95TDZLdkNuVHU3andmbTNydDFTNlRLWHNSV0dRMC81MTA0UUd3Q2dCY29qWk00cnF3M0FDSXVlVVEKalhIUktLd0dCNDN6VnVrbDQ5RTZsWW1wdWI5LzJqVVczNmFwd0ZYYXUyZzNmTlNpUGZxWWJwVUh0QjB6SGtCawpoRkxKM0xXYjJSU0pRbjkzaExYczM3SmhTUU02WWExTk1RY2FlUkxyM2FoTTIwTTFQalU5c3BCMTVlclFnMC9EClFJQVExWmgwUGtkTVB6eFJlSHpTdjMzZUZHY1FDZVJNNHoyZW9jNUh2d2NjeUZnUU84VVhaeURMSm1BY1E5S2oKY3FnZUd3QzBGM1p4cEVPWEtJR3BHZmg3eFg4MnhGWUhodEhDeE5PZnQ3QlIvdnRZNW9GcWpTdEgrd3dWandJRApBUUFCbzRHck1JR29NQTRHQTFVZER3RUIvd1FFQXdJSGdEQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBakFNCkJnTlZIUk1CQWY4RUFqQUFNRHdHQ0NzR0FRVUZCd0VCQkRBd0xqQXNCZ2dyQmdFRkJRY3dBWVlnYUhSMGNEb3YKTDJObGNuUnpMbUZqY3k1aGJHbDVkVzR1WTI5dEwyOWpjM0F3TlFZRFZSMGZCQzR3TERBcW9DaWdKb1lrYUhSMApjRG92TDJObGNuUnpMbUZqY3k1aGJHbDVkVzR1WTI5dEwzSnZiM1F1WTNKc01BMEdDU3FHU0liM0RRRUJDd1VBCkE0SUJBUUJXdTNUMzNlQVVOSHZKeTdxYnBKUTlpSUNmWVJ0S2pTVlJKK21oMXE0SzJ0SmtJS3ZiOFh5cTZmbUEKNWI1Qk95QjFyZDFFVUI5ZDJSVFVoMjJxa21EaWFEcFE5bk8wSjNKRnhMQU5xbHFjNjl3RDhYU0k5bE5qVTVZZQorTDdJSVk3MHcwMTlNM0g0elUwd1kzVWVreFRCZC8reCtxRHEyaHJoWUpPbGgrdHBlSmRmMGc1QTR2aWQzY21tCmV1QjlmbDV5SjNyby9BNmd6bm5heGpNY21waHN3UElZVGYrdGJnR0J5S21scGlhU01IdXB6allWbm4zUEVsYjQKUFZOZ1NqVzU1Y0NHVlNoRTVjaDRmbytzKy9UVm9ZV3pmVmNzdW12djZGZG90YUpRQ1dIQU02azlKTlZiYmdDNQpoL0tsVGFrcUZMTk5idXBheEVQSnpwRmNtaUxxCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBcEo3b20wTk1LeFpOUkU1RDVuWXQwcGNWN1MvcGY0b3lMNkt2Q25UdTdqd2ZtM3J0CjFTNlRLWHNSV0dRMC81MTA0UUd3Q2dCY29qWk00cnF3M0FDSXVlVVFqWEhSS0t3R0I0M3pWdWtsNDlFNmxZbXAKdWI5LzJqVVczNmFwd0ZYYXUyZzNmTlNpUGZxWWJwVUh0QjB6SGtCa2hGTEozTFdiMlJTSlFuOTNoTFhzMzdKaApTUU02WWExTk1RY2FlUkxyM2FoTTIwTTFQalU5c3BCMTVlclFnMC9EUUlBUTFaaDBQa2RNUHp4UmVIelN2MzNlCkZHY1FDZVJNNHoyZW9jNUh2d2NjeUZnUU84VVhaeURMSm1BY1E5S2pjcWdlR3dDMEYzWnhwRU9YS0lHcEdmaDcKeFg4MnhGWUhodEhDeE5PZnQ3QlIvdnRZNW9GcWpTdEgrd3dWandJREFRQUJBb0lCQUFMU0lrUSswL2hOQ29mbwpHMnZBaktwMklrOE5LaUFnV3huTDNObitCUFlhRzZTTFo3WG1kV2taamNPSS9BdUJSRFp5MC9SbjZ5NXdaY0xnCjFoVC9BVmpHSHhGOWFNc2NuNEhUb2Q3VVllelVjZitMKzFlT2UzOWV0NFNmazNzVFBZdEdqdVRacytvQitFaTAKend2OEVCc3RtVXRYSzlSWFhGTk04Y2tzNi94ZkpxVU9RVHhxVXhuZHhwMndDSUM2RWZlMkw5T1Q2QjVhMGw1UQo1aWh5ZmhQQlJBeVpFbFRhOGIvL2h4aGRhdU14N1BySUZ3Wk1tT0M2TDg4SDlSSmtKb0hOZHc1eENHUko4a09DCnNUOHlaZUhjcGw5Tm15YzBVUFQzTm5NdFpUR1pjaGRLanliNllodnhwK2p5bzdnK1FodHl3TXZIWWM4MWhVQzcKMGFZZklORUNnWUVBMDQrd0RtUjcwNFk3VUhFZHltdy9YSEd6bkZPRkNyWVdXaEFEditTci9XRE9td3RsUTJFaApmWXVWYTE2d1pzVW5MY0VsNDFwYVZzOXdOVERJakN1eWZhQ3hOOEZ2VVBEeHp5OGs4Y3I1MW8remEzbVNhUkxZCkRWSE16WTcvakhWdWIyYTFkY0trN2MwQmszUDFVbkhYTFh6cTVnUlpvdXQ4dHhUYktSamdxT2tDZ1lFQXh6TVUKdU4zS1RmZEkyQ3VXdjFtRXdXVVU3L1QvTkVaQTZ5QlNzMnNaVWRNWWtWUVViNDAvNHh0RCt1T2ZBZ3AxU285UApsc3FNa2JlVzJTK3BRRzRVU2o1Qm8yVkR2ZG5vVzBOa1QzZEtxOFZUWGtmMjFCUG4zN0swQ0V3Qy9RWG9OaHpqCkxjZ2xDVXBjZHlDa05VOGRwZ3Nvd2N5TEFqWnc0SXhiYm5TU1A3Y0NnWUJnTG93cER1L295N2I5ckYrUjNzS3oKb1pHNXVaTGJ1c3JRcVVVN0laZzd1cDVUaU12QjVVL1hodlVvZWtVU2hBRjY0THY3NytEd1pLQ3IzZ0RmRVNLMQowSytoSEpVaUpGaWJDK0RzK0kyN1NWdVZ1aENoS29zRkN6SmtKZVh5a3BUaG1yMVd5MlkySXFUYng3VTVoVDRCCmxUQXA0TUpydWtuWjVtWjQrYkZ4dVFLQmdRQ2lEY2haN1BWY0lFUyt1QmRYYkRnNExVZXZQeDB2SmNoQ2dIVkgKU1dXN3o0UTVGckhaWG93TzhtdUhmQTRyMXQ0ODNnSGRwc0pjK1lKYkJnOG5QMlo2VDlPT1hoK1NIK2lMOW5Odwp3cGVZemx0WVpDdEZ0VHY2SEtPaDdGU3lDMUF5VmFYcjVOdGNoNFpaMDlCREhpMzhteTk1R2pJc2hxV2x5QW5KCi9rUE1XUUtCZ0dvL0xuT2hzd1pUV2hQUDVGR0NWbmdHNWhWOW1PWjRsTEI1MitTcG10VFMwQ1NKbVhCN1hMRTIKbDFXb2ZtSGx1azlQSy95dFphZ2hLMXd1QVVuVnovRmk5UnByS0tKQWZ4S0liaWVCTVZ6TC93b3F0MzYyOGRXRApYVGh5VXRRRS96MVNpbmRsdHZDMXR2cWQ1ZzRYN0JWaSs2NDlHV3NLcm9zVnNYMVFmUjlrCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== diff --git a/deploy-ease-core/src/main/resources/kube/config3 b/deploy-ease-core/src/main/resources/kube/config3 new file mode 100644 index 0000000..ecd6768 --- /dev/null +++ b/deploy-ease-core/src/main/resources/kube/config3 @@ -0,0 +1,19 @@ +apiVersion: v1 +clusters: +- cluster: + server: https://10.201.127.46:6443 + certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQ2akNDQXRLZ0F3SUJBZ0lDRHhzd0RRWUpLb1pJaHZjTkFRRUxCUUF3YWpFcU1DZ0dBMVVFQ2hNaFl6TTQKTUdVNFpHWm1ORFZoTXpRME1HSTRaamhrWm1SaE1qSTNaV05qWm1FMk1SQXdEZ1lEVlFRTEV3ZGtaV1poZFd4MApNU293S0FZRFZRUURFeUZqTXpnd1pUaGtabVkwTldFek5EUXdZamhtT0dSbVpHRXlNamRsWTJObVlUWXdIaGNOCk1qTXdOVEU1TURJek16QXdXaGNOTkRNd05URTBNREl6T0RVMldqQnFNU293S0FZRFZRUUtFeUZqTXpnd1pUaGsKWm1ZME5XRXpORFF3WWpobU9HUm1aR0V5TWpkbFkyTm1ZVFl4RURBT0JnTlZCQXNUQjJSbFptRjFiSFF4S2pBbwpCZ05WQkFNVElXTXpPREJsT0dSbVpqUTFZVE0wTkRCaU9HWTRaR1prWVRJeU4yVmpZMlpoTmpDQ0FTSXdEUVlKCktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU9FTmlzRWtSblNsSDhtRDJFUkFoS2ZWdWkyN0hTUFMKQTViT2lKdDZWNnRxVHhmTWRwR0RIMTVCbFlKL1laMFZyeERGUjVyMkJBREVkcXdsVG10NWozTFVIcXN6MnRoKwp2RzFrY0UyMmhUdFNtR05KQjhjbzA2YWNxaHV6YlhMbEZMQlc5eURNVnNENWc4RFBvZzh4QnFXZGg2NVRqeGx5ClkwZjJLeUVBS2V6YUFzc3RHV0swSDIvU2EvenZlb25GNnBJREtKcHh6SjZOSTZ5dUdlTk5hRkMwYXNTTVRJSjIKZHFGT01uWFpFdmZqTVlhU2QxWk5FdFUweUxkYzEyRDlVRmJUamxMSEZxcG9rYit2a202T0tGNi9iOUhCN0xXNgpsZFZMTFdHUkhrbS81Vmg5NTVnOVJFUUNVYVN4THpiSkwrVzlBU3puWWJlcnc0RUtpWWxjSUkwQ0F3RUFBYU9CCm1UQ0JsakFPQmdOVkhROEJBZjhFQkFNQ0Fxd3dEd1lEVlIwVEFRSC9CQVV3QXdFQi96QThCZ2dyQmdFRkJRY0IKQVFRd01DNHdMQVlJS3dZQkJRVUhNQUdHSUdoMGRIQTZMeTlqWlhKMGN5NWhZM011WVd4cGVYVnVMbU52YlM5dgpZM053TURVR0ExVWRId1F1TUN3d0txQW9vQ2FHSkdoMGRIQTZMeTlqWlhKMGN5NWhZM011WVd4cGVYVnVMbU52CmJTOXliMjkwTG1OeWJEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTVJOVjF0K1F6TUo5ZDlkekNDZzVULzkKQnI2T2piQVFSeHhodkVDV0JmODVOeEZUWDNYRmMzbVpkcytNeWFRRERhcUhjbzRmNGZHZ3hKRjVldmZ6cWlTZApVUVZYYktVRlFGVVgvZklnNHlDM290NWxSakw3QjR1VDJyYnI0dEhNYkUySy92ZGVUTXVBNUo0Z0pHV0IvRzBqCmtWSldYYmNJVVFDbGZzMUVQZDQ5b2VDdzBianRXOG9HSkt3S2NYYTloK1U1QytCVktTN21LNm9veUFqQ0kzRE4KNW9NS0VCdlM0aElqdFBTYjJlOE5HOWNCaGd2TXRTU2pITGRXaHpINUlrZ013dWJTUldMOEJqRDd1SzVFWmJteQpOMzNMSGFldEFIMTZQM0IvT0F0WGJWcmk2aWM2Q2lLbXBseTdhWnlGcitEeW92b2NpdjNxNFRtZVVwaHNRQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + name: kubernetes +contexts: +- context: + cluster: kubernetes + user: "298101684398995518" + name: 298101684398995518-c380e8dff45a3440b8f8dfda227eccfa6 +current-context: 298101684398995518-c380e8dff45a3440b8f8dfda227eccfa6 +kind: Config +preferences: {} +users: +- name: "298101684398995518" + user: + client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQwVENDQXJtZ0F3SUJBZ0lDRDNrd0RRWUpLb1pJaHZjTkFRRUxCUUF3YWpFcU1DZ0dBMVVFQ2hNaFl6TTQKTUdVNFpHWm1ORFZoTXpRME1HSTRaamhrWm1SaE1qSTNaV05qWm1FMk1SQXdEZ1lEVlFRTEV3ZGtaV1poZFd4MApNU293S0FZRFZRUURFeUZqTXpnd1pUaGtabVkwTldFek5EUXdZamhtT0dSbVpHRXlNamRsWTJObVlUWXdIaGNOCk1qTXdOVEkwTURZME16QXdXaGNOTWpZd05USXpNRFkwT0RJMVdqQS9NUlV3RXdZRFZRUUtFd3h6ZVhOMFpXMDYKZFhObGNuTXhDVEFIQmdOVkJBc1RBREViTUJrR0ExVUVBeE1TTWprNE1UQXhOamcwTXprNE9UazFOVEU0TUlJQgpJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBcU85R3YyRWJsUWt5ZFJmR2FTK0NabndVClMyZXFRaUJTL1JxRlVyRTlxR2dsYWtMS0g3aGZmMjdXZXppVTNzQWJQT2RLUEtSQWpSZy9jcnc4WTRXVTV0clAKWUZIb2IwTnoyMjVWcFl1YUlGWnhIVzRLTTlqSzM1Q0dQNmJDK3FCOXBGV0JxcDl1bkJKS0RKbFBSUUJLUDVucQpRRmx6aG0wQ2E1a2haNXovNWczeitpRlVWck1zazlJWGVDc2dFeE5kMjE1ckRHUUhKRVhkSlB2T2RpVmlJTUF4CmdtNmI5SzRHVUZnRXVWa0tROU1lNTVQQ2NuMnVYbnFZRVA1ckZZSU81SUFtVFlhV016NUJCZnZDTDZiRndocEIKMVR5UHVNWjRkWXZjZkNXVmNFQWpuZDdmMEN0aHdEL2FiYTNsT1JGbTB4UFVLSzRxY1FTM1kxYWhHaURBc1FJRApBUUFCbzRHck1JR29NQTRHQTFVZER3RUIvd1FFQXdJSGdEQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBakFNCkJnTlZIUk1CQWY4RUFqQUFNRHdHQ0NzR0FRVUZCd0VCQkRBd0xqQXNCZ2dyQmdFRkJRY3dBWVlnYUhSMGNEb3YKTDJObGNuUnpMbUZqY3k1aGJHbDVkVzR1WTI5dEwyOWpjM0F3TlFZRFZSMGZCQzR3TERBcW9DaWdKb1lrYUhSMApjRG92TDJObGNuUnpMbUZqY3k1aGJHbDVkVzR1WTI5dEwzSnZiM1F1WTNKc01BMEdDU3FHU0liM0RRRUJDd1VBCkE0SUJBUUNJV0VSZzFUU3IrUEg2bHh1enhTd2lEWHlGbWoxdXJZays1clhKUVZQSnVmYlF5T2ZremRIUThGWWkKSGQ5bUQxQVVKKzNGQWh1Yyt0aUFzaDZXbW5oK0s3Q1k2K0xJRWZNYm5hWlJzckQ1R1M0YjJMYWJRUE5QWXVXQQoyNjVIWWNwV1BOUE5ENFNWV1VWbGRvNi9TZmdoY2RyZG1jUERMcG56SWUzaTdKQ0NYWEJmbDNjZTdWUXU0Vk53CkVzVGQ0ZURGYTdoTlBWZ25yanVmZjBCNzZjU1hySGJkblEzdmFFcnBGUXh4elNCSnFnQTUwY0gwT21xMXRHUWEKWlZlbzBjWkRpS28rTmdnVm9xVUNtanpab0JZZjRkUmVnQXUzZ3g5eEhqVGRpY0hrRTkrdmNmS2xtRy9xZ01oRQpCbzl5WFVtc0IyUTN1b0UrRkxjZ1VTTmRodXk2Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBcU85R3YyRWJsUWt5ZFJmR2FTK0NabndVUzJlcVFpQlMvUnFGVXJFOXFHZ2xha0xLCkg3aGZmMjdXZXppVTNzQWJQT2RLUEtSQWpSZy9jcnc4WTRXVTV0clBZRkhvYjBOejIyNVZwWXVhSUZaeEhXNEsKTTlqSzM1Q0dQNmJDK3FCOXBGV0JxcDl1bkJKS0RKbFBSUUJLUDVucVFGbHpobTBDYTVraFo1ei81ZzN6K2lGVQpWck1zazlJWGVDc2dFeE5kMjE1ckRHUUhKRVhkSlB2T2RpVmlJTUF4Z202YjlLNEdVRmdFdVZrS1E5TWU1NVBDCmNuMnVYbnFZRVA1ckZZSU81SUFtVFlhV016NUJCZnZDTDZiRndocEIxVHlQdU1aNGRZdmNmQ1dWY0VBam5kN2YKMEN0aHdEL2FiYTNsT1JGbTB4UFVLSzRxY1FTM1kxYWhHaURBc1FJREFRQUJBb0lCQUFoL3FSNTlveWFYUk51UgpLNkVsQzdsZUtxTTBmdU0rdnc0T3BJQnBmRUdabzdBNTFmTk1ramxWK1NKUDBXVjNZcWRvdDFwZnBRTzBJWlVECkZVS29lTG80YmRCWnJvalNhdVN5STBybHdBWTZjd3hZK2RocjRxRG1vMnBXV0Y3RmJpeXpSSWV4NTUyZ2FldEMKVnpPUWRTdkg4WG4xUmhPUUxsdjlZeW5VUXlkdW5WZndtY0NsM2ZsVjZqY3BoaHJYNmgrNzZjOVRGQXRpUDFlWAprNXNsOVUrZzl5N3ZlbzFEY2s4eXBENnZSMlF1MldKWlZLRDQycG52Y0YrUzlEYlA4UWRFLytlZ0Y5OEhSRitmClBoMHNaa2ErQ3R5dHVOWnVXaW5hN3hBRnI0cDRndXZ2U1RXVm02enpHU3ZhSkJZRC9CSjVQVThieGQ2NGRMNlAKVXVka0d2VUNnWUVBMEc5V09WbHJ5U0ZrMnhhOXk3T0RMSm13QXlJL0J3VkF3c2VUd0VOUjIxT1MxdmV1ajFYWgozc0p3emlubEpBTCt4dm9Sem0xbWljRnlDMUhqM1VZaytPck1IM1RyOW9sWnZ0VFhSbjNZeWtjUEl3Ny9acXlsCkV1dzhrZWZBSVJFZlV5YVlCUzNvOG5DUUtyVDdyWEV2Z0lOWUJGWVFCL0dpSW93Z1NUZ2RMSnNDZ1lFQXozeGIKQWd1c1I4b0ZPWUJ0bnBNZWNXdHp2WjRqTDVyWDIwQTN2bm9qc3hlS2QxdEJ3aTEzRnZjeUI2TDZuQ1NNS24xQQp6MFVJbENGREVqZzA1SHRDc3MzOGRRNHVIUG16eXdob2NiazRBeWdYcHVqNnA2MDdYS3NuN2xiWG9PMnV6SXlKCkp5QWpid2ozejN1UWNsQmhFOXF5UnpjOXN4MUszUGtQajg5MHJxTUNnWUJwSzRScU00QjdYK292MGUyNlZyMmQKUjM3VVZmZFBaNHNodk9vRVhQTjBvMXE0TlFsVE1aSlpIK3NqVzJoUEgyUEdxbTlKcFZIVHVGUCsramJyYzNVOApVOXpqRW0vdFdhaDY3WkloODJYcnlxY01uWWlwR2Z2QTdJb3paS2hCQnc2ek9nb0Nzd09UTU5ETmU3eHg2Mlo0CmhjMW5nclZjRE1RdWdsM1lGQVJFZVFLQmdHNTJhMUZVZTUwZ3ZkVldQWVllRnlnVkorSjhyWWpyckI0TE8ySksKVG5WTGhDbDFTVFlpMUhOQ21iMGRGTVZLWStFL0crRDloTXF3UnJBTmdvTmQ2QzJmb3RlQy9DUHJBTUNJTW1yUgpURFBLQllXVUpkWmRVT3hPSncwcDZOVEJsYjFLMkw0ZXl4NlRMTE9tdWtsUjU4MFZNckxkZ3hpMzhLSmlhdG1LCmZqbDNBb0dBYTlMVDZtTm9qejc1OVB2eCtwNEJoemhRakpSQm1ITUNLdUNoTnFYTkxwTmx3MXJscHluUDFjcXgKNlhjL09iUVdrSHJEVUpUb2VyamZPS05HTkl4cUdOcDdHMm5GVWorT290UElkVEpKU1ErQVNtWU5HSlJWVUJIWQpWYmNLWENSZE1yQTNoNFB2RUl2V0M4d21iZEtaYnBLYUI0NzdVeEF3S2gxYmpEcnU1OWs9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== \ No newline at end of file diff --git a/deploy-ease-core/src/main/resources/sql/dictionary.sql b/deploy-ease-core/src/main/resources/sql/dictionary.sql new file mode 100644 index 0000000..0d22a82 --- /dev/null +++ b/deploy-ease-core/src/main/resources/sql/dictionary.sql @@ -0,0 +1,15 @@ +USE deploy_ease_dev; +DROP TABLE IF EXISTS dictionary; +CREATE TABLE dictionary +( + id INT AUTO_INCREMENT PRIMARY KEY, + dictionary_code VARCHAR(50) NOT NULL, + dictionary_name VARCHAR(50) NOT NULL, + dictionary_value TEXT, + status TINYINT NOT NULL DEFAULT 1 COMMENT '1、有效 0、无效', + tenant_sharing TINYINT NOT NULL DEFAULT 1 COMMENT '1、共享 0、不共享', + create_time DATETIME NOT NULL DEFAULT NOW(), + update_time DATETIME NOT NULL DEFAULT NOW(), + is_deleted TINYINT NOT NULL DEFAULT 0 +); +INSERT INTO dictionary ( dictionary_code, dictionary_name, dictionary_value) VALUE ('JENKINS_BASE_API', 'Jenkins地址', 'http://jenkins-rd.longi.com:8080'); diff --git a/deploy-ease-core/src/main/resources/sql/project.sql b/deploy-ease-core/src/main/resources/sql/project.sql new file mode 100644 index 0000000..419af2e --- /dev/null +++ b/deploy-ease-core/src/main/resources/sql/project.sql @@ -0,0 +1,16 @@ +USE deploy_ease_dev; +DROP TABLE IF EXISTS project; +CREATE TABLE project +( + id INT AUTO_INCREMENT PRIMARY KEY, + project_code VARCHAR(50) NOT NULL, + project_name VARCHAR(50) NOT NULL, + tenant_code VARCHAR(50) NOT NULL, + create_time DATETIME NOT NULL DEFAULT NOW(), + update_time DATETIME NOT NULL DEFAULT NOW(), + is_deleted TINYINT NOT NULL DEFAULT 0 +); +INSERT INTO project (project_code, project_name, tenant_code) +VALUES ('scp', '计划产品', 'longi'); +INSERT INTO project (project_code, project_name, tenant_code) +VALUES ('oms', '订单', 'longi'); \ No newline at end of file diff --git a/deploy-ease-core/src/main/resources/sql/project_environment.sql b/deploy-ease-core/src/main/resources/sql/project_environment.sql new file mode 100644 index 0000000..8aab76d --- /dev/null +++ b/deploy-ease-core/src/main/resources/sql/project_environment.sql @@ -0,0 +1,20 @@ +USE deploy_ease_dev; +DROP TABLE IF EXISTS project_environment; +CREATE TABLE project_environment +( + id INT AUTO_INCREMENT PRIMARY KEY, + environment_code VARCHAR(50) NOT NULL, + environment_name VARCHAR(50) NOT NULL, + environment_type TINYINT NOT NULL COMMENT '1、K8S 2、Docker 3、单点部署', + project_code VARCHAR(50) NOT NULL, + is_vpn TINYINT NOT NULL, + create_time DATETIME NOT NULL DEFAULT NOW(), + update_time DATETIME NOT NULL DEFAULT NOW(), + is_deleted TINYINT NOT NULL DEFAULT 0 +); +INSERT INTO project_environment (environment_code, environment_name, environment_type, is_vpn, project_code) +VALUES ('dev', '开发环境', 1, 1, 'scp'); +INSERT INTO project_environment (environment_code, environment_name, environment_type, is_vpn, project_code) +VALUES ('uat', '测试环境', 1, 1, 'scp'); +INSERT INTO project_environment (environment_code, environment_name, environment_type, is_vpn, project_code) +VALUES ('prod', '生产环境', 1, 1, 'scp'); \ No newline at end of file diff --git a/deploy-ease-core/src/main/resources/sql/tenant.sql b/deploy-ease-core/src/main/resources/sql/tenant.sql new file mode 100644 index 0000000..94ee7af --- /dev/null +++ b/deploy-ease-core/src/main/resources/sql/tenant.sql @@ -0,0 +1,13 @@ +USE deploy_ease_dev; +DROP TABLE IF EXISTS tenant; +CREATE TABLE tenant +( + id INT AUTO_INCREMENT PRIMARY KEY, + tenant_code VARCHAR(50) NOT NULL, + tenant_name VARCHAR(50) NOT NULL, + enabled TINYINT NOT NULL DEFAULT 1 COMMENT '1、有效 2、无效', + create_time DATETIME NOT NULL DEFAULT NOW(), + update_time DATETIME NOT NULL DEFAULT NOW(), + is_deleted TINYINT NOT NULL DEFAULT 0 +); +INSERT INTO tenant (tenant_code, tenant_name, enabled) VALUES ('longi', '隆基', 1); \ No newline at end of file diff --git a/deploy-ease-core/src/main/resources/sql/tenant_dictionary.sql b/deploy-ease-core/src/main/resources/sql/tenant_dictionary.sql new file mode 100644 index 0000000..5653aa0 --- /dev/null +++ b/deploy-ease-core/src/main/resources/sql/tenant_dictionary.sql @@ -0,0 +1,16 @@ +USE deploy_ease_dev; +DROP TABLE IF EXISTS tenant_dictionary; +CREATE TABLE tenant_dictionary +( + id INT AUTO_INCREMENT PRIMARY KEY, + dictionary_code VARCHAR(50) NOT NULL, + dictionary_name VARCHAR(50) NOT NULL, + dictionary_value TEXT, + status TINYINT NOT NULL DEFAULT 1 COMMENT '1、有效 0、无效', + tenant_code VARCHAR(50) NOT NULL, + create_time DATETIME NOT NULL DEFAULT NOW(), + update_time DATETIME NOT NULL DEFAULT NOW(), + is_deleted TINYINT NOT NULL DEFAULT 0 +); +INSERT INTO tenant_dictionary (dictionary_code, dictionary_name, dictionary_value, tenant_code) +VALUES ('JENKINS_BASE_API', 'Jenkins地址', 'http://jenkins-rd.longi.com:8080', 'longi'); \ No newline at end of file diff --git a/deploy-ease-core/src/main/resources/sql/user.sql b/deploy-ease-core/src/main/resources/sql/user.sql new file mode 100644 index 0000000..0a35ec4 --- /dev/null +++ b/deploy-ease-core/src/main/resources/sql/user.sql @@ -0,0 +1,13 @@ +USE deploy_ease_dev; +DROP TABLE IF EXISTS user; +CREATE TABLE user +( + id INT AUTO_INCREMENT PRIMARY KEY, + user_name VARCHAR(50) NOT NULL, + password VARCHAR(200) NOT NULL, + real_name VARCHAR(50) NOT NULL, + create_time DATETIME NOT NULL DEFAULT NOW(), + update_time DATETIME NOT NULL DEFAULT NOW(), + is_deleted TINYINT NOT NULL DEFAULT 0 +); +INSERT INTO user(user_name, password, real_name)VALUES ('admin', '123456', '管理员'); \ No newline at end of file diff --git a/deploy-ease-core/src/main/resources/sql/user_online.sql b/deploy-ease-core/src/main/resources/sql/user_online.sql new file mode 100644 index 0000000..848c55d --- /dev/null +++ b/deploy-ease-core/src/main/resources/sql/user_online.sql @@ -0,0 +1,13 @@ +USE deploy_ease_dev; +DROP TABLE IF EXISTS user_online; +CREATE TABLE user_online +( + id INT AUTO_INCREMENT PRIMARY KEY, + user_code VARCHAR(50) NOT NULL, + ip_address VARCHAR(200) NOT NULL, + last_time DATETIME NOT NULL, + quit_time DATETIME NOT NULL, + create_time DATETIME NOT NULL DEFAULT NOW(), + update_time DATETIME NOT NULL DEFAULT NOW(), + is_deleted TINYINT NOT NULL DEFAULT 0 +) \ No newline at end of file diff --git a/deploy-ease-core/src/main/resources/sql/user_tenant.sql b/deploy-ease-core/src/main/resources/sql/user_tenant.sql new file mode 100644 index 0000000..6a1cb6a --- /dev/null +++ b/deploy-ease-core/src/main/resources/sql/user_tenant.sql @@ -0,0 +1,12 @@ +USE deploy_ease_dev; +DROP TABLE IF EXISTS user_tenant; +CREATE TABLE user_tenant +( + id INT AUTO_INCREMENT PRIMARY KEY, + user_id VARCHAR(50) NOT NULL, + tenant_code VARCHAR(50) NOT NULL, + create_time DATETIME NOT NULL DEFAULT NOW(), + update_time DATETIME NOT NULL DEFAULT NOW(), + is_deleted TINYINT NOT NULL DEFAULT 0 +); +INSERT INTO user_tenant (user_id, tenant_code) VALUES ('1', 'longi') \ No newline at end of file diff --git a/deploy-ease-synchronizer/pom.xml b/deploy-ease-synchronizer/pom.xml new file mode 100644 index 0000000..1457798 --- /dev/null +++ b/deploy-ease-synchronizer/pom.xml @@ -0,0 +1,113 @@ + + + 4.0.0 + deploy-ease-synchronizer + + + + + org.springframework.boot + spring-boot + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-web + + + org.projectlombok + lombok + ${lombok.version} + provided + + + com.alibaba + transmittable-thread-local + ${transmittable-thread-local.version} + + + org.apache.httpcomponents.client5 + httpclient5 + ${http5.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + cn.hutool + hutool-all + ${hutool.version} + + + io.kubernetes + client-java + ${kubernetes.version} + + + org.freemarker + freemarker + ${freemarker.version} + + + com.alibaba.fastjson2 + fastjson2 + ${fastjson-version} + + + com.squareup.okhttp3 + okhttp + ${okhttp3.version} + + + org.mapstruct + mapstruct + ${mapstruct.version} + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + org.mapstruct + mapstruct-jdk8 + ${mapstruct.version} + + + com.qc.soft + deploy-ease-api + 1.0-SNAPSHOT + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + com.alibaba.nacos + nacos-client + + + + + + com.qc.soft + deploy-ease + 1.0-SNAPSHOT + + + \ No newline at end of file diff --git a/deploy-ease-synchronizer/src/main/java/com/qc/soft/deploy/ease/synchronizer/DeployEaseSynchronizerApplication.java b/deploy-ease-synchronizer/src/main/java/com/qc/soft/deploy/ease/synchronizer/DeployEaseSynchronizerApplication.java new file mode 100644 index 0000000..d9358c1 --- /dev/null +++ b/deploy-ease-synchronizer/src/main/java/com/qc/soft/deploy/ease/synchronizer/DeployEaseSynchronizerApplication.java @@ -0,0 +1,18 @@ +package com.qc.soft.deploy.ease.synchronizer; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +@SpringBootConfiguration +@EnableAutoConfiguration +@EnableScheduling +@EnableAsync +public class DeployEaseSynchronizerApplication { + + public static void main(String[] args) { + SpringApplication.run(DeployEaseSynchronizerApplication.class, args); + } +} diff --git a/deploy-ease-synchronizer/src/main/resources/application.yml b/deploy-ease-synchronizer/src/main/resources/application.yml new file mode 100644 index 0000000..e69de29 diff --git a/deploy-ease-synchronizer/src/main/resources/bootstrap.yml b/deploy-ease-synchronizer/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..3ac7ca3 --- /dev/null +++ b/deploy-ease-synchronizer/src/main/resources/bootstrap.yml @@ -0,0 +1,27 @@ +spring: + cloud: + nacos: + server-addr: ${NACOS_CONFIG_SERVER} + username: ${NACOS_USER} + password: ${NACOS_PWD} + discovery: + group: ${DEPLOY_ENV} + namespace: ${DEPLOY_ENV} + enabled: true + config: + group: ${DEPLOY_ENV} + namespace: ${DEPLOY_ENV} + extension-configs[0]: + data-id: common.yml + group: common + refresh: false + extension-configs[1]: + data-id: deploy-ease-synchronizer.yml + group: business + refresh: false + config: + override-none: false + allow-override: true + override-system-properties: false + main: + allow-bean-definition-overriding: true \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..5de6cbe --- /dev/null +++ b/pom.xml @@ -0,0 +1,88 @@ + + + 4.0.0 + com.qc.soft + deploy-ease + 1.0-SNAPSHOT + pom + + + 8 + 8 + UTF-8 + 2.3.0.RELEASE + 2.3.31 + 2.0.51 + 1.6.0.RC1 + 1.18.22 + 8.0.23 + 1.1.10 + 3.2.1 + 3.6.2 + 2.14.5 + 5.3.1 + 3.10 + 5.8.16 + 19.0.1 + 4.9.1 + 2.3.0 + 2.2.9.RELEASE + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + org.projectlombok + lombok + ${lombok.version} + provided + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + ${nacos-cloud.version} + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + ${nacos-cloud.version} + + + com.alibaba.nacos + nacos-client + ${nacos-client.version} + + + + + + deploy-ease-core + deploy-ease-api + deploy-ease-synchronizer + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.6.0 + + + + repackage + + + + + + + \ No newline at end of file