Skip to content

Commit

Permalink
kubeconfig 수정정
Browse files Browse the repository at this point in the history
  • Loading branch information
hyun123 committed Jan 15, 2025
1 parent c30f214 commit 27ff1be
Show file tree
Hide file tree
Showing 8 changed files with 302 additions and 228 deletions.
2 changes: 1 addition & 1 deletion bin/main/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ aes:
key: fb1755281b0ca6184a0ee644e6477ee7

cbtumblebug:
url: ${TUMBLEBUG_URL:210.217.178.130}
url: ${TUMBLEBUG_URL:13.125.215.182}
port: ${TUMBLEBUG_PORT:1323}
id: ${TUMBLEBUG_ID:default}
pass: ${TUMBLEBUG_PASSWORD:default}
Expand Down
19 changes: 0 additions & 19 deletions kubeconfig

This file was deleted.

20 changes: 17 additions & 3 deletions src/main/java/kr/co/mcmp/ape/cbtumblebug/dto/K8sClusterDto.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package kr.co.mcmp.ape.cbtumblebug.dto;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonProperty;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;
import lombok.ToString;

@Data
@NoArgsConstructor
@ToString
@AllArgsConstructor
@ApiModel(description = "K8s Cluster 정보")
public class K8sClusterDto {
Expand Down Expand Up @@ -69,6 +72,7 @@ public class K8sClusterDto {

@Data
@NoArgsConstructor
@ToString
@AllArgsConstructor
public static class ConnectionConfig {
@JsonProperty("configName")
Expand Down Expand Up @@ -105,6 +109,7 @@ public static class ConnectionConfig {
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public static class RegionZoneInfo {
@JsonProperty("assignedRegion")
private String assignedRegion;
Expand All @@ -116,6 +121,7 @@ public static class RegionZoneInfo {
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public static class RegionDetail {
@JsonProperty("regionId")
private String regionId;
Expand All @@ -136,6 +142,7 @@ public static class RegionDetail {
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public static class Location {
@JsonProperty("display")
private String display;
Expand All @@ -150,6 +157,7 @@ public static class Location {
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public static class CspViewK8sClusterDetail {
@JsonProperty("IId")
private IID iid;
Expand Down Expand Up @@ -180,6 +188,7 @@ public static class CspViewK8sClusterDetail {
}

@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public static class IID {
Expand All @@ -191,6 +200,7 @@ public static class IID {
}

@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public static class Network {
Expand All @@ -210,6 +220,7 @@ public static class Network {
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public static class NodeGroup {
@JsonProperty("IId")
private IID iid;
Expand Down Expand Up @@ -254,6 +265,7 @@ public static class NodeGroup {
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public static class AccessInfo {
@JsonProperty("Endpoint")
private String endpoint;
Expand All @@ -265,6 +277,7 @@ public static class AccessInfo {
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public static class Addons {
@JsonProperty("KeyValueList")
private List<KeyValue> keyValueList;
Expand All @@ -273,6 +286,7 @@ public static class Addons {
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public static class KeyValue {
@JsonProperty("key")
private String key;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,85 +1,115 @@
package kr.co.mcmp.softwarecatalog.kubernetes.service;

import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

import org.springframework.stereotype.Service;

import com.marcnuri.helm.Helm;
import com.marcnuri.helm.InstallCommand;
import com.marcnuri.helm.Release;

import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import kr.co.mcmp.ape.cbtumblebug.api.CbtumblebugRestApi;
import kr.co.mcmp.ape.cbtumblebug.dto.K8sClusterDto;
import kr.co.mcmp.softwarecatalog.SoftwareCatalog;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
@RequiredArgsConstructor
public class HelmChartService {
private final CbtumblebugRestApi api;

public Release deployHelmChart(String namespace, SoftwareCatalog catalog) {
public Release deployHelmChart(KubernetesClient client, String namespace, SoftwareCatalog catalog,
String clusterName) {
Path tempConfigFile = null;
K8sClusterDto dto = api.getK8sClusterByName(namespace, clusterName);
String cspType = dto.getConnectionConfig().getProviderName().toUpperCase();
log.info("CSP Type: {}", cspType);

try {
addHelmRepository(catalog);
String kubeconfig = dto.getCspViewK8sClusterDetail().getAccessInfo().getKubeconfig();

// Helm 설치 명령어 구성
InstallCommand installCommand = Helm.install(
catalog.getHelmChart().getRepositoryName() + "/" + catalog.getHelmChart().getChartName())
.withName(catalog.getHelmChart().getChartName())
.withNamespace(namespace)
.withVersion(catalog.getHelmChart().getChartVersion())
.set("replicaCount", catalog.getMinReplicas())
.set("image.repository", catalog.getHelmChart().getImageRepository())
.set("image.tag", "latest")
.set("image.pullPolicy", "Always")
.set("service.port", catalog.getDefaultPort())
.set("resources.requests.cpu", catalog.getMinCpu().toString())
.set("resources.requests.memory", catalog.getMinMemory() + "Mi")
.set("resources.limits.cpu", catalog.getRecommendedCpu().toString())
.set("resources.limits.memory", catalog.getRecommendedMemory() + "Mi");

// HPA 설정 추가
// GCP의 경우 gke-gcloud-auth-plugin 관련 설정 제거
if ("GCP".equalsIgnoreCase(cspType)) {
kubeconfig = kubeconfig.replaceAll("command:\\s*gke-gcloud-auth-plugin", "")
.replaceAll("apiVersion:\\s*client.authentication.k8s.io/.*\\n", "")
.replaceAll("installHint:.*\\n", "")
.replaceAll("provideClusterInfo:.*\\n", "");
}
tempConfigFile = createTempKubeconfigFile(kubeconfig);

InstallCommand installCommand = createInstallCommand(catalog, namespace, tempConfigFile);
applyCspSpecificSettings(installCommand, cspType);

// HPA 설정
if (Boolean.TRUE.equals(catalog.getHpaEnabled())) {
installCommand
.set("autoscaling.enabled", true)
.set("autoscaling.minReplicas", catalog.getMinReplicas())
.set("autoscaling.maxReplicas", catalog.getMaxReplicas())
.set("autoscaling.targetCPUUtilizationPercentage", catalog.getCpuThreshold().intValue())
.set("autoscaling.targetMemoryUtilizationPercentage", catalog.getMemoryThreshold().intValue());
.set("autoscaling.targetCPUUtilizationPercentage", catalog.getCpuThreshold())
.set("autoscaling.targetMemoryUtilizationPercentage", catalog.getMemoryThreshold());
}

// Helm 차트 설치 실행

Release result = installCommand.call();

log.info("Helm Chart '{}' 버전 '{}'가 네임스페이스 '{}'에 배포됨 (HPA: {})",
catalog.getHelmChart().getChartName(),
"latest",
namespace,
catalog.getHpaEnabled());
log.info("Helm Chart '{}' 배포 완료 - namespace: {}, CSP: {}",
catalog.getHelmChart().getChartName(),
namespace,
cspType);
return result;

} catch (Exception e) {
log.error("Helm Chart 배포 중 오류 발생", e);
log.error("Helm Chart 배포 중 오류 발생 - CSP: {}", cspType, e);
throw new RuntimeException("Helm Chart 배포 실패", e);
} finally {
deleteTempFile(tempConfigFile);
}
}

public void uninstallHelmChart(String namespace, SoftwareCatalog catalog) {
try {
String result = Helm.uninstall(catalog.getHelmChart().getChartName())

private InstallCommand createInstallCommand(SoftwareCatalog catalog, String namespace, Path configFile) {
return Helm.install(catalog.getHelmChart().getRepositoryName() + "/" + catalog.getHelmChart().getChartName())
.withKubeConfig(configFile)
.withName(catalog.getHelmChart().getChartName())
.withNamespace(namespace)
.call();

boolean deleted = result != null && !result.isEmpty();

if (deleted) {
log.info("Helm Release '{}' 가 네임스페이스 '{}'에서 삭제됨",
catalog.getHelmChart().getChartName(), namespace);
} else {
log.warn("Helm Release '{}' 삭제 실패",
catalog.getHelmChart().getChartName());
}
} catch (Exception e) {
log.error("Helm Release 삭제 중 오류 발생", e);
throw new RuntimeException("Helm Release 삭제 실패", e);
.withVersion(catalog.getHelmChart().getChartVersion())
.set("replicaCount", catalog.getMinReplicas())
.set("image.repository", catalog.getHelmChart().getImageRepository())
.set("image.tag", "latest")
.set("image.pullPolicy", "Always")
.set("service.port", catalog.getDefaultPort())
.set("resources.requests.cpu", catalog.getMinCpu().toString())
.set("resources.requests.memory", catalog.getMinMemory() + "Mi")
.set("resources.limits.cpu", catalog.getRecommendedCpu().toString())
.set("resources.limits.memory", catalog.getRecommendedMemory() + "Mi")
.set("persistence.enabled", false)
.set("securityContext.enabled", false)
.set("serviceAccount.create", true)
.withTimeout(300)
.waitReady();
}

private void applyCspSpecificSettings(InstallCommand command, String cspType) {
log.info("Applying CSP specific settings for: {}", cspType);
switch (cspType) {
case "GCP":
command.set("gcp.auth.enabled", false)
.set("serviceAccount.annotations.iam\\.gke\\.io/gcp-service-account", "false")
.set("rbac.create", true);
break;
case "AZURE":
command.set("azure.auth.enabled", false)
.set("serviceAccount.annotations.azure\\.workload\\.identity/use", "false");
break;
default:
log.warn("알 수 없는 CSP 타입: {}", cspType);
}
}

Expand All @@ -90,4 +120,54 @@ private void addHelmRepository(SoftwareCatalog catalog) throws Exception {
.call();
Helm.repo().update();
}
}

private Path createTempKubeconfigFile(String kubeconfig) throws IOException {
Path tempFile = Files.createTempFile("kubeconfig", ".yaml");
Files.write(tempFile, kubeconfig.getBytes(StandardCharsets.UTF_8));
return tempFile;
}

private void deleteTempFile(Path tempFile) {
if (tempFile != null) {
try {
Files.deleteIfExists(tempFile);
} catch (IOException e) {
log.warn("임시 파일 삭제 실패: {}", tempFile, e);
}
}
}

public void uninstallHelmChart(String namespace, SoftwareCatalog catalog, String clusterName) {
Path tempConfigFile = null;
try {
K8sClusterDto dto = api.getK8sClusterByName(namespace, clusterName);
String cspType = dto.getConnectionConfig().getProviderName().toUpperCase();
String kubeconfig = dto.getCspViewK8sClusterDetail().getAccessInfo().getKubeconfig();

// GCP의 경우 gke-gcloud-auth-plugin 관련 설정 제거
if ("GCP".equalsIgnoreCase(cspType)) {
kubeconfig = kubeconfig.replaceAll("command:\\s*gke-gcloud-auth-plugin", "")
.replaceAll("apiVersion:\\s*client.authentication.k8s.io/.*\\n", "")
.replaceAll("installHint:.*\\n", "")
.replaceAll("provideClusterInfo:.*\\n", "");
}
tempConfigFile = createTempKubeconfigFile(kubeconfig);

String result = Helm.uninstall(catalog.getHelmChart().getChartName())
.withKubeConfig(tempConfigFile)
.withNamespace(namespace)
.call();

log.info("Helm Release '{}' 삭제 완료 - namespace: {}, CSP: {}",
catalog.getHelmChart().getChartName(),
namespace,
cspType);

} catch (Exception e) {
log.error("Helm Release 삭제 실패", e);
throw new RuntimeException("Helm Release 삭제 실패", e);
} finally {
deleteTempFile(tempConfigFile);
}
}
}
Loading

0 comments on commit 27ff1be

Please sign in to comment.