11package kr .co .mcmp .softwarecatalog .kubernetes .service ;
22
33import java .io .IOException ;
4+ import java .io .StringWriter ;
45import java .net .URI ;
56import java .nio .charset .StandardCharsets ;
67import java .nio .file .Files ;
78import java .nio .file .Path ;
89
910import org .springframework .stereotype .Service ;
11+ import org .yaml .snakeyaml .DumperOptions ;
12+ import org .yaml .snakeyaml .Yaml ;
1013
1114import com .marcnuri .helm .Helm ;
1215import com .marcnuri .helm .InstallCommand ;
1316import com .marcnuri .helm .Release ;
1417
1518import io .fabric8 .kubernetes .client .Config ;
1619import io .fabric8 .kubernetes .client .KubernetesClient ;
17- import kr .co .mcmp .ape .cbtumblebug .api .CbtumblebugRestApi ;
18- import kr .co .mcmp .ape .cbtumblebug .dto .K8sClusterDto ;
1920import kr .co .mcmp .softwarecatalog .SoftwareCatalog ;
2021import lombok .RequiredArgsConstructor ;
2122import lombok .extern .slf4j .Slf4j ;
2425@ Slf4j
2526@ RequiredArgsConstructor
2627public class HelmChartService {
27- private final CbtumblebugRestApi api ;
2828
29- public Release deployHelmChart (KubernetesClient client , String namespace , SoftwareCatalog catalog ,
30- String clusterName ) {
31- Path tempConfigFile = null ;
32- K8sClusterDto dto = api .getK8sClusterByName (namespace , clusterName );
29+
30+
31+ public String convertConfigToYaml (Config config ) {
32+ // SnakeYAML 설정
33+ DumperOptions options = new DumperOptions ();
34+ options .setDefaultFlowStyle (DumperOptions .FlowStyle .BLOCK ); // 블록 스타일 (가독성이 좋음)
35+ Yaml yaml = new Yaml (options );
36+
37+ // Config 객체를 YAML로 직렬화
38+ StringWriter writer = new StringWriter ();
39+ yaml .dump (config , writer );
40+
41+ return writer .toString ();
42+ }
43+ public Release deployHelmChart (KubernetesClient client , String namespace , SoftwareCatalog catalog ) {
44+ Path tempKubeconfigPath = null ;
45+
3346 try {
47+ // Helm repository 추가
3448 addHelmRepository (catalog );
35- String kubeconfig = dto .getCspViewK8sClusterDetail ().getAccessInfo ().getKubeconfig ();
36- tempConfigFile = createTempKubeconfigFile (kubeconfig );
3749
50+ Config kubeConfig = client .getConfiguration ();
51+ log .info ("===========================kubeconfig" );
52+ log .info (kubeConfig .toString ()); // Config 객체 로그 확인
53+ log .info ("===========================================" );
54+
55+ // Config 객체를 YAML로 변환
56+ String kubeconfigYaml = convertConfigToYaml (kubeConfig ); // Config를 YAML 형식으로 직렬화
57+ log .info (kubeconfigYaml );
58+ // 임시 kubeconfig 파일 생성
59+ tempKubeconfigPath = createTempKubeconfigFile (kubeConfig .toString ()); // YAML 파일로 저장
60+
61+ // Helm 설치 명령어 생성
3862 InstallCommand installCommand = Helm .install (
3963 catalog .getHelmChart ().getRepositoryName () + "/" + catalog .getHelmChart ().getChartName ())
40- .withKubeConfig (tempConfigFile )
64+ .withKubeConfig (tempKubeconfigPath ) // Path 타입으로 kubeconfig 전달
4165 .withName (catalog .getHelmChart ().getChartName ())
4266 .withNamespace (namespace )
43- // .withVersion(catalog.getHelmChart().getChartVersion())
67+ .withVersion (catalog .getHelmChart ().getChartVersion ())
4468 .set ("replicaCount" , catalog .getMinReplicas ())
4569 .set ("image.repository" , catalog .getHelmChart ().getImageRepository ())
4670 .set ("image.tag" , "latest" )
@@ -49,81 +73,86 @@ public Release deployHelmChart(KubernetesClient client, String namespace, Softwa
4973 .set ("resources.requests.cpu" , catalog .getMinCpu ().toString ())
5074 .set ("resources.requests.memory" , catalog .getMinMemory () + "Mi" )
5175 .set ("resources.limits.cpu" , catalog .getRecommendedCpu ().toString ())
52- .set ("resources.limits.memory" , catalog .getRecommendedMemory () + "Mi" )
53- .set ("persistence.enabled" , false )
54- .set ("securityContext.enabled" , false )
55- .set ("serviceAccount.create" , true )
56- // .with(300)
57- .waitReady ();
76+ .set ("resources.limits.memory" , catalog .getRecommendedMemory () + "Mi" );
5877
78+ // HPA 설정 추가
5979 if (Boolean .TRUE .equals (catalog .getHpaEnabled ())) {
6080 installCommand
61- .set ("autoscaling.enabled" , true )
62- .set ("autoscaling.minReplicas" , catalog .getMinReplicas ())
63- .set ("autoscaling.maxReplicas" , catalog .getMaxReplicas ())
64- .set ("autoscaling.targetCPUUtilizationPercentage" , catalog .getCpuThreshold ())
65- .set ("autoscaling.targetMemoryUtilizationPercentage" , catalog .getMemoryThreshold ());
81+ .set ("autoscaling.enabled" , true )
82+ .set ("autoscaling.minReplicas" , catalog .getMinReplicas ())
83+ .set ("autoscaling.maxReplicas" , catalog .getMaxReplicas ())
84+ .set ("autoscaling.targetCPUUtilizationPercentage" , catalog .getCpuThreshold (). intValue ())
85+ .set ("autoscaling.targetMemoryUtilizationPercentage" , catalog .getMemoryThreshold (). intValue ());
6686 }
6787
88+ // Helm 차트 설치 실행
6889 Release result = installCommand .call ();
69- log .info ("Helm Chart '{}' 배포 완료 - namespace: {}" ,
70- catalog .getHelmChart ().getChartName (),
71- namespace );
90+
91+ log .info ("Helm Chart '{}' 버전 '{}'가 네임스페이스 '{}'에 배포됨 (HPA: {})" ,
92+ catalog .getHelmChart ().getChartName (),
93+ "latest" ,
94+ namespace ,
95+ catalog .getHpaEnabled ());
7296 return result ;
7397
7498 } catch (Exception e ) {
7599 log .error ("Helm Chart 배포 중 오류 발생" , e );
76100 throw new RuntimeException ("Helm Chart 배포 실패" , e );
77101 } finally {
78- deleteTempFile (tempConfigFile );
102+ // 임시 kubeconfig 파일 삭제
103+ if (tempKubeconfigPath != null ) {
104+ try {
105+ deleteTempFile (tempKubeconfigPath );
106+ } catch (IOException e ) {
107+ log .warn ("임시 kubeconfig 파일 삭제 실패: {}" , tempKubeconfigPath , e );
108+ }
109+ }
110+ }
111+ }
112+
113+ public void uninstallHelmChart (String namespace , SoftwareCatalog catalog ) {
114+ try {
115+ String result = Helm .uninstall (catalog .getHelmChart ().getChartName ())
116+ .withNamespace (namespace )
117+ .call ();
118+
119+ boolean deleted = result != null && !result .isEmpty ();
120+
121+ if (deleted ) {
122+ log .info ("Helm Release '{}' 가 네임스페이스 '{}'에서 삭제됨" ,
123+ catalog .getHelmChart ().getChartName (), namespace );
124+ } else {
125+ log .warn ("Helm Release '{}' 삭제 실패" ,
126+ catalog .getHelmChart ().getChartName ());
127+ }
128+ } catch (Exception e ) {
129+ log .error ("Helm Release 삭제 중 오류 발생" , e );
130+ throw new RuntimeException ("Helm Release 삭제 실패" , e );
79131 }
80132 }
81133
82134 private void addHelmRepository (SoftwareCatalog catalog ) throws Exception {
83135 Helm .repo ().add ()
84- .withName (catalog .getHelmChart ().getRepositoryName ())
85- .withUrl (URI .create (catalog .getHelmChart ().getChartRepositoryUrl ()))
86- .call ();
136+ .withName (catalog .getHelmChart ().getRepositoryName ())
137+ .withUrl (URI .create (catalog .getHelmChart ().getChartRepositoryUrl ()))
138+ .call ();
87139 Helm .repo ().update ();
88140 }
89141
142+ // kubeconfig 형식이 유효한지 확인하는 메서드
143+ private boolean isValidKubeconfig (String kubeconfig ) {
144+ return kubeconfig .contains ("apiVersion" ) && kubeconfig .contains ("kind" );
145+ }
146+
147+ // 임시 kubeconfig 파일 생성
90148 private Path createTempKubeconfigFile (String kubeconfig ) throws IOException {
91149 Path tempFile = Files .createTempFile ("kubeconfig" , ".yaml" );
92150 Files .write (tempFile , kubeconfig .getBytes (StandardCharsets .UTF_8 ));
93151 return tempFile ;
94152 }
95153
96- private void deleteTempFile (Path tempFile ) {
97- if (tempFile != null ) {
98- try {
99- Files .deleteIfExists (tempFile );
100- } catch (IOException e ) {
101- log .warn ("임시 파일 삭제 실패: {}" , tempFile , e );
102- }
103- }
104- }
105-
106- public void uninstallHelmChart (String namespace , SoftwareCatalog catalog , String clusterName ) {
107- Path tempConfigFile = null ;
108- try {
109- K8sClusterDto dto = api .getK8sClusterByName (namespace , clusterName );
110- String kubeconfig = dto .getCspViewK8sClusterDetail ().getAccessInfo ().getKubeconfig ();
111- tempConfigFile = createTempKubeconfigFile (kubeconfig );
112-
113- String result = Helm .uninstall (catalog .getHelmChart ().getChartName ())
114- .withKubeConfig (tempConfigFile )
115- .withNamespace (namespace )
116- .call ();
117-
118- log .info ("Helm Release '{}' 삭제 완료 - namespace: {}" ,
119- catalog .getHelmChart ().getChartName (),
120- namespace );
121-
122- } catch (Exception e ) {
123- log .error ("Helm Release 삭제 실패" , e );
124- throw new RuntimeException ("Helm Release 삭제 실패" , e );
125- } finally {
126- deleteTempFile (tempConfigFile );
127- }
154+ // 임시 kubeconfig 파일 삭제
155+ private void deleteTempFile (Path tempFile ) throws IOException {
156+ Files .deleteIfExists (tempFile );
128157 }
129158}
0 commit comments