Skip to content

Commit

Permalink
update application install for VM
Browse files Browse the repository at this point in the history
  • Loading branch information
hyun123 committed Oct 7, 2024
1 parent 387de52 commit f6e56ab
Show file tree
Hide file tree
Showing 13 changed files with 601 additions and 434 deletions.
7 changes: 7 additions & 0 deletions bin/main/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,10 @@ cbtumblebug:
port: 1323
id: default
pass: default

file:
upload:
path:
windows: C:/mcmp/uploads/
linux: /home/mcmp/uploads/
allowed-extensions: jpg,jpeg,png,gif
3 changes: 2 additions & 1 deletion bin/main/jenkins/kubernetes_helm_install_pipeline.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="[email protected]_11dd">
<flow-definition plugin="[email protected]_11dd" name="vm_application_install">

<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
Expand Down
320 changes: 214 additions & 106 deletions bin/main/jenkins/vm_application_install_pipeline.xml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,23 @@ public ResponseWrapper<String> triggerVmInstall(@RequestBody JenkinsJobDto.VmApp
return triggerJenkinsJob(jobDto);
}

@PostMapping("/vm/uninstall")
@Operation(summary = "Uninstall VM Application", description = "VM에서 애플리케이션을 제거하기 위해 Jenkins 작업을 트리거합니다.")
public ResponseWrapper<String> triggerVmUninstall(@RequestBody JenkinsJobDto.VmApplicationUninstall jobDto) {
return triggerJenkinsJob(jobDto);
}

@PostMapping("/helm/install")
@Operation(summary = "Install Kubernetes Helm Chart", description = "Kubernetes에 Helm 차트를 설치하기 위해 Jenkins 작업을 트리거합니다.")
public ResponseWrapper<String> triggerHelmInstall(@RequestBody JenkinsJobDto.KubernetesHelmInstall jobDto) {
return triggerJenkinsJob(jobDto);
}

@PostMapping("/helm/uninstall")
@Operation(summary = "Uninstall Kubernetes Helm Release", description = "Kubernetes에서 Helm 릴리스를 제거하기 위해 Jenkins 작업을 트리거합니다.")
public ResponseWrapper<String> triggerHelmUninstall(@RequestBody JenkinsJobDto.KubernetesHelmUninstall jobDto) {
return triggerJenkinsJob(jobDto);
}
// @PostMapping("/vm/uninstall")
// @Operation(summary = "Uninstall VM Application", description = "VM에서 애플리케이션을 제거하기 위해 Jenkins 작업을 트리거합니다.")
// public ResponseWrapper<String> triggerVmUninstall(@RequestBody JenkinsJobDto.VmApplicationUninstall jobDto) {
// return triggerJenkinsJob(jobDto);
// }

// @PostMapping("/helm/install")
// @Operation(summary = "Install Kubernetes Helm Chart", description = "Kubernetes에 Helm 차트를 설치하기 위해 Jenkins 작업을 트리거합니다.")
// public ResponseWrapper<String> triggerHelmInstall(@RequestBody JenkinsJobDto.KubernetesHelmInstall jobDto) {
// return triggerJenkinsJob(jobDto);
// }

// @PostMapping("/helm/uninstall")
// @Operation(summary = "Uninstall Kubernetes Helm Release", description = "Kubernetes에서 Helm 릴리스를 제거하기 위해 Jenkins 작업을 트리거합니다.")
// public ResponseWrapper<String> triggerHelmUninstall(@RequestBody JenkinsJobDto.KubernetesHelmUninstall jobDto) {
// return triggerJenkinsJob(jobDto);
// }

private ResponseWrapper<String> triggerJenkinsJob(JenkinsJobDto jobDto) {
try {
Expand All @@ -73,15 +73,15 @@ private ResponseWrapper<String> triggerJenkinsJob(JenkinsJobDto jobDto) {
}
}

@GetMapping("/job/status/{jobId}")
public ResponseWrapper<String> getJobStatus(@PathVariable String jobId) {
try {
String status = appProvEngineService.getJobStatus(jobId);
return new ResponseWrapper<>(status);
} catch (Exception e) {
return new ResponseWrapper<>("Failed to get job status: " + e.getMessage());
}
}
// @GetMapping("/job/status/{jobId}")
// public ResponseWrapper<String> getJobStatus(@PathVariable String jobId) {
// try {
// String status = appProvEngineService.getJobStatus(jobId);
// return new ResponseWrapper<>(status);
// } catch (Exception e) {
// return new ResponseWrapper<>("Failed to get job status: " + e.getMessage());
// }
// }

@GetMapping("/ns")
@Operation(summary = "모든 네임스페이스 조회", description = "시스템에 등록된 모든 네임스페이스를 조회합니다.")
Expand Down
111 changes: 5 additions & 106 deletions src/main/java/kr/co/mcmp/ape/dto/reqDto/JenkinsJobDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
@Schema(description = "Jenkins 작업 DTO")
public abstract class JenkinsJobDto {

@Schema(description = "CB-Tumblebug Swagger URI", example = "http://localhost:1323/tumblebug")
private String cbTumblebugSwaggerUri;
@Schema(description = "Namespace", example = "ns01")
private String namespace;
@Schema(description = "MCIS 이름", example = "my-mcis")
private String mcisName;
private String mciName;

@JsonIgnore
@Schema(hidden = true)
Expand All @@ -29,21 +29,16 @@ public abstract class JenkinsJobDto {

public Map<String, List<String>> convertToJenkinsParams() {
Map<String, List<String>> params = new HashMap<>();
params.put("CB_TUMBLEBUG_SWAGGER_URI", List.of(this.cbTumblebugSwaggerUri));
params.put("MCIS_NAME", List.of(this.mcisName));
params.put("NAMESPACE", List.of(this.namespace));
params.put("MCI_ID", List.of(this.mciName));
params.putAll(convertToSpecificParams());
return params;
}


@Getter
@Setter
@Schema(description = "VM 애플리케이션 설치 작업")
public static class VmApplicationInstall extends JenkinsJobDto {
@Schema(description = "사용자 이름", example = "admin")
private String user;
@Schema(description = "사용자 비밀번호", example = "password")
private String userpass;
@Schema(description = "설치할 애플리케이션 목록", example = "[\"nginx\", \"mysql\"]")
private List<String> applications;

Expand All @@ -57,104 +52,8 @@ public String getJobName() {
@Override
public Map<String, List<String>> convertToSpecificParams() {
Map<String, List<String>> params = new HashMap<>();
params.put("USER", List.of(this.user));
params.put("USERPASS", List.of(this.userpass));
params.put("APPLICATIONS", List.of(String.join(",", this.applications)));
return params;
}

}

@Getter
@Setter
@Schema(description = "VM 애플리케이션 제거 작업")
public static class VmApplicationUninstall extends JenkinsJobDto {
@Schema(description = "사용자 이름", example = "admin")
private String user;
@Schema(description = "사용자 비밀번호", example = "password")
private String userpass;
@Schema(description = "설치할 애플리케이션 목록", example = "[\"nginx\", \"mysql\"]")
private List<String> applications;

@Override
@JsonIgnore
@Schema(hidden = true)
public String getJobName() {
return "vm_application_uninstall";
}

@Override
public Map<String, List<String>> convertToSpecificParams() {
Map<String, List<String>> params = new HashMap<>();
params.put("USER", List.of(this.user));
params.put("USERPASS", List.of(this.userpass));
params.put("APPLICATIONS", List.of(String.join(",", this.applications)));
return params;
}

}

@Getter
@Setter
@Schema(description = "Kubernetes Helm 차트 설치 작업")
public static class KubernetesHelmInstall extends JenkinsJobDto {

@Schema(description = "Kubernetes 네임스페이스", example = "default")
private String namespace;
@Schema(description = "클라우드 연결 이름", example = "aws-conn-01")
private String cloudConnectionName;
@Schema(description = "Helm 릴리스 이름", example = "my-release")
private String helmReleaseName;
@Schema(description = "Helm 차트 이름", example = "stable/mysql")
private String helmChartName;
@Schema(description = "Helm 차트 버전", example = "1.6.3")
private String helmChartVersion;

@Override
@JsonIgnore
@Schema(hidden = true)
public String getJobName() {
return "kubernetes_helm_install";
}

@Override
public Map<String, List<String>> convertToSpecificParams() {
Map<String, List<String>> params = new HashMap<>();
params.put("NAMESPACE", List.of(this.namespace));
params.put("CLOUD_CONNECTION_NAME", List.of(this.cloudConnectionName));
params.put("HELM_RELEASE_NAME", List.of(this.helmReleaseName));
params.put("HELM_CHART_NAME", List.of(this.helmChartName));
params.put("HELM_CHART_VERSION", List.of(this.helmChartVersion));
return params;
}

}

@Getter
@Setter
@Schema(description = "Kubernetes Helm 릴리스 제거 작업")
public static class KubernetesHelmUninstall extends JenkinsJobDto {
@Schema(description = "Kubernetes 네임스페이스", example = "default")
private String namespace;
@Schema(description = "클라우드 연결 이름", example = "aws-conn-01")
private String cloudConnectionName;
@Schema(description = "Helm 릴리스 이름", example = "my-release")
private String helmReleaseName;

@Override
@JsonIgnore
@Schema(hidden = true)
public String getJobName() {
return "kubernetes_helm_uninstall";
}

@Override
public Map<String, List<String>> convertToSpecificParams() {
Map<String, List<String>> params = new HashMap<>();
params.put("NAMESPACE", List.of(this.namespace));
params.put("CLOUD_CONNECTION_NAME", List.of(this.cloudConnectionName));
params.put("HELM_RELEASE_NAME", List.of(this.helmReleaseName));
return params;
}
}
}
15 changes: 15 additions & 0 deletions src/main/java/kr/co/mcmp/ape/entity/JobConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package kr.co.mcmp.ape.entity;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
public class JobConfig {

private String jobName;
private String xmlContent;

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ public interface AppProvEngineService {

List<ApeLogResDto> getApeLog(String jobName);

String getJobStatus(String jobId);

String triggerJenkinsJob(JenkinsJobDto dto);

}
30 changes: 24 additions & 6 deletions src/main/java/kr/co/mcmp/ape/service/AppProvEngineServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

Expand All @@ -30,6 +31,20 @@ public class AppProvEngineServiceImpl implements AppProvEngineService {
@Autowired
private OssService ossService;

@Value("${cbtumblebug.url}")
private String tumblebugUrl;

@Value("${cbtumblebug.port}")
private String tumblebugPort;

@Value("${cbtumblebug.id}")
private String tumblebugId;

@Value("${cbtumblebug.pass}")
private String tumblebugPass;



private static final int MAX_LOGS = 100; // 최대 로그 갯수 제한

@Override
Expand Down Expand Up @@ -87,16 +102,16 @@ private Optional<ApeLogResDto> fetchSingleLog(OssDto ossDto, int buildNumber, St
}
}

@Override
public String getJobStatus(String jobId) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getJobStatus'");
}

@Override
public String triggerJenkinsJob(JenkinsJobDto jobDto) {
OssDto jenkinsOss = getJenkinsOss();
Map<String, List<String>> jenkinsJobParams = jobDto.convertToJenkinsParams();
String tumblebugUri = makeTumblebugUri(tumblebugUrl, tumblebugPort);
log.info("tumblebugUri : {}", tumblebugUri);
jenkinsJobParams.put("CB_TUMBLEBUG_URI", List.of(tumblebugUri));
jenkinsJobParams.put("TUMBLEBUG_USER", List.of(tumblebugId));
jenkinsJobParams.put("TUMBLEBUG_PASSWORD", List.of(tumblebugPass));
int buildNumber = jenkinsService.buildJenkinsJob(
jenkinsOss,
jobDto.getJobName(),
Expand All @@ -107,5 +122,8 @@ public String triggerJenkinsJob(JenkinsJobDto jobDto) {
return String.valueOf(buildNumber);
}


private String makeTumblebugUri(String url, String port){
StringBuilder builder = new StringBuilder();
return builder.append("http://").append(url).append(":").append(port).append("/tumblebug").toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@
import com.cdancy.jenkins.rest.domain.job.BuildInfo;
import com.cdancy.jenkins.rest.domain.job.JobInfo;

import kr.co.mcmp.ape.entity.JobConfig;
import kr.co.mcmp.ape.service.jenkins.api.JenkinsRestApi;
import kr.co.mcmp.ape.service.jenkins.model.JenkinsCredential;
import kr.co.mcmp.ape.service.jenkins.service.JenkinsService.JobCreationResult;
import kr.co.mcmp.exception.McmpException;
import kr.co.mcmp.oss.dto.OssDto;
import kr.co.mcmp.response.ResponseCode;
Expand All @@ -54,10 +56,10 @@ public class JenkinsService {
private static final String PIPELINE_XML_PATH = "/flow-definition/definition/script";

private static final List<String> PIPELINE_XML_FILE_PATHS = Arrays.asList(
"jenkins/vm_application_install_pipeline.xml",
"jenkins/vm_application_uninstall_pipeline.xml",
"jenkins/kubernetes_helm_install_pipeline.xml",
"jenkins/kubernetes_helm_uninstall_pipeline.xml"
"jenkins/vm_application_install_pipeline.xml"
// "jenkins/vm_application_uninstall_pipeline.xml",
// "jenkins/kubernetes_helm_install_pipeline.xml",
// "jenkins/kubernetes_helm_uninstall_pipeline.xml"
);

enum JobCreationResult {
Expand Down Expand Up @@ -119,35 +121,38 @@ public boolean createJenkinsJob_v2(OssDto jenkins, String jenkinsJobName, String
}
*/

public List<String> getXmlContents() {
public List<JobConfig> getJobConfigs() {
return PIPELINE_XML_FILE_PATHS.stream()
.map(this::readXmlFile)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}


private String readXmlFile(String filePath) {
private JobConfig readXmlFile(String filePath) {
try (InputStream inputStream = getClass().getResourceAsStream("/"+filePath)) {
if (inputStream == null) {
log.error("File not found: {}", filePath);
return null;
}
return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
Document doc = XMLUtil.getDocument(inputStream);
Element flowDefinitionElement = (Element) doc.getElementsByTagName("flow-definition").item(0);
String jobName = flowDefinitionElement.getAttribute("name");
String xmlContent = XMLUtil.XmlToString(doc);
return new JobConfig(jobName, xmlContent);
} catch (IOException e) {
log.error("Error reading Jenkins pipeline XML file: {}", e.getMessage(), e);
return null;
}
}

public void createJenkinsDefaultJobs(OssDto jenkins) {
List<String> xmlContents = getXmlContents();
List<String> jobNames = Arrays.asList("vm_application_install", "vm_application_uninstall", "helm_application_install", "helm_application_uninstall");

Map<JobCreationResult, Long> resultCounts = IntStream.range(0, jobNames.size())
.mapToObj(i -> {
String jobName = jobNames.get(i);
String xmlContent = xmlContents.get(i);
List<JobConfig> jobConfigs = getJobConfigs();

Map<JobCreationResult, Long> resultCounts = jobConfigs.stream()
.map(jobConfig -> {
String jobName = jobConfig.getJobName();
String xmlContent = jobConfig.getXmlContent();
if(!isExistJobName(jenkins, jobName)){
RequestStatus status = createSingleJenkinsJob(jenkins, jobName, xmlContent);
if (status.value()) {
Expand Down
Loading

0 comments on commit f6e56ab

Please sign in to comment.