From 160f94cf1a9e4eb2a8e4a74ab1e602570e2d8a7d Mon Sep 17 00:00:00 2001 From: dev4unet Date: Mon, 15 Jul 2024 08:35:43 +0000 Subject: [PATCH 01/32] Converting Korean output string to English --- .../drivers/aws/main/Test_Resources.go | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go index 47dd39da7..6f79a1a2d 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go @@ -78,9 +78,9 @@ func handleSecurity() { case 1: result, err := handler.ListSecurity() if err != nil { - cblogger.Infof(" Security 목록 조회 실패 : ", err) + cblogger.Infof(" Security List Lookup Failed : ", err) } else { - cblogger.Info("Security 목록 조회 결과") + cblogger.Info("Security List Lookup Result") cblogger.Info(result) if result != nil { @@ -401,9 +401,9 @@ func handlePublicIP() { fmt.Println("Start ListPublicIP() ...") result, err := handler.ListPublicIP() if err != nil { - cblogger.Error("PublicIP 목록 조회 실패 : ", err) + cblogger.Error("PublicIP List Lookup Failed : ", err) } else { - cblogger.Info("PublicIP 목록 조회 결과") + cblogger.Info("PublicIP List Lookup Result") spew.Dump(result) } @@ -491,9 +491,9 @@ func handleKeyPair() { case 1: result, err := KeyPairHandler.ListKey() if err != nil { - cblogger.Infof(" 키 페어 목록 조회 실패 : ", err) + cblogger.Infof(" 키 페어 List Lookup Failed : ", err) } else { - cblogger.Info("키 페어 목록 조회 결과") + cblogger.Info("키 페어 List Lookup Result") //cblogger.Info(result) spew.Dump(result) } @@ -575,9 +575,9 @@ func handleVNetwork() { case 1: result, err := VPCHandler.ListVNetwork() if err != nil { - cblogger.Infof(" VNetwork 목록 조회 실패 : ", err) + cblogger.Infof(" VNetwork List Lookup Failed : ", err) } else { - cblogger.Info("VNetwork 목록 조회 결과") + cblogger.Info("VNetwork List Lookup Result") //cblogger.Info(result) spew.Dump(result) @@ -690,9 +690,9 @@ func handleVPC() { case 1: result, err := VPCHandler.ListVPC() if err != nil { - cblogger.Infof(" VNetwork 목록 조회 실패 : ", err) + cblogger.Infof(" VNetwork List Lookup Failed : ", err) } else { - cblogger.Info("VNetwork 목록 조회 결과") + cblogger.Info("VNetwork List Lookup Result") //cblogger.Info(result) spew.Dump(result) @@ -798,11 +798,11 @@ func handleImage() { case 1: result, err := handler.ListImage() if err != nil { - cblogger.Infof(" Image 목록 조회 실패 : ", err) + cblogger.Infof(" Image List Lookup Failed : ", err) } else { - cblogger.Info("Image 목록 조회 결과") + cblogger.Info("Image List Lookup Result") cblogger.Debug(result) - cblogger.Infof("로그 레벨 : [%s]", cblog.GetLevel()) + cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) //spew.Dump(result) cblogger.Info("출력 결과 수 : ", len(result)) @@ -887,9 +887,9 @@ func handleVNic() { case 1: result, err := handler.ListVNic() if err != nil { - cblogger.Infof(" VNic 목록 조회 실패 : ", err) + cblogger.Infof(" VNic List Lookup Failed : ", err) } else { - cblogger.Info("VNic 목록 조회 결과") + cblogger.Info("VNic List Lookup Result") spew.Dump(result) if len(result) > 0 { reqVnicID = result[0].Id // 조회 및 삭제 편의를 위해 목록의 첫번째 ID로 변경 @@ -1153,9 +1153,9 @@ func handleVMSpec() { fmt.Println("Start ListVMSpec() ...") result, err := handler.ListVMSpec() if err != nil { - cblogger.Error("VMSpec 목록 조회 실패 : ", err) + cblogger.Error("VMSpec List Lookup Failed : ", err) } else { - cblogger.Debug("VMSpec 목록 조회 결과") + cblogger.Debug("VMSpec List Lookup Result") //spew.Dump(result) cblogger.Debug(result) cblogger.Infof("전체 목록 개수 : [%d]", len(result)) @@ -1179,9 +1179,9 @@ func handleVMSpec() { fmt.Println("Start ListOrgVMSpec() ...") result, err := handler.ListOrgVMSpec() if err != nil { - cblogger.Error("VMSpec Org 목록 조회 실패 : ", err) + cblogger.Error("VMSpec Org List Lookup Failed : ", err) } else { - cblogger.Debug("VMSpec Org 목록 조회 결과") + cblogger.Debug("VMSpec Org List Lookup Result") //spew.Dump(result) cblogger.Debug(result) //spew.Dump(result) @@ -1283,11 +1283,11 @@ func handleNLB() { case 1: result, err := handler.ListNLB() if err != nil { - cblogger.Infof(" NLB 목록 조회 실패 : ", err) + cblogger.Infof(" NLB List Lookup Failed : ", err) } else { - cblogger.Info("NLB 목록 조회 결과") + cblogger.Info("NLB List Lookup Result") cblogger.Debug(result) - cblogger.Infof("로그 레벨 : [%s]", cblog.GetLevel()) + cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) //spew.Dump(result) cblogger.Info("출력 결과 수 : ", len(result)) @@ -1497,11 +1497,11 @@ func handleCluster() { case 1: result, err := handler.ListCluster() if err != nil { - cblogger.Infof(" Cluster 목록 조회 실패 : ", err) + cblogger.Infof(" Cluster List Lookup Failed : ", err) } else { - cblogger.Info("Cluster 목록 조회 결과") + cblogger.Info("Cluster List Lookup Result") cblogger.Debug(result) - cblogger.Infof("로그 레벨 : [%s]", cblog.GetLevel()) + cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) //spew.Dump(result) cblogger.Info("출력 결과 수 : ", len(result)) @@ -1657,12 +1657,12 @@ func handleRegionZone() { case 1: result, err := handler.ListRegionZone() if err != nil { - cblogger.Infof("ListRegionZone 목록 조회 실패 : %s", err) + cblogger.Infof("ListRegionZone List Lookup Failed : %s", err) } else { - cblogger.Info("ListRegionZone 목록 조회 결과") + cblogger.Info("ListRegionZone List Lookup Result") // cblogger.Debugf("결과 %s", result[0]) spew.Dump(result) - cblogger.Infof("로그 레벨 : [%s]", cblog.GetLevel()) + cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) //spew.Dump(result) cblogger.Info("출력 결과 수 : ", len(result)) } @@ -1674,29 +1674,29 @@ func handleRegionZone() { } else { cblogger.Info("GetRegionZone 조회 결과") cblogger.Debug(result) - cblogger.Infof("로그 레벨 : [%s]", cblog.GetLevel()) + cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) // spew.Dump(result) } case 3: result, err := handler.ListOrgRegion() if err != nil { - cblogger.Infof("ListOrgRegion 목록 조회 실패 : ", err) + cblogger.Infof("ListOrgRegion List Lookup Failed : ", err) } else { - cblogger.Info("ListOrgRegion 목록 조회 결과") + cblogger.Info("ListOrgRegion List Lookup Result") cblogger.Debug(result) - cblogger.Infof("로그 레벨 : [%s]", cblog.GetLevel()) + cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) //spew.Dump(result) cblogger.Info("출력 결과 수 : ", len(result)) } case 4: result, err := handler.ListOrgZone() if err != nil { - cblogger.Infof("ListOrgZone 목록 조회 실패 : %s", err) + cblogger.Infof("ListOrgZone List Lookup Failed : %s", err) } else { - cblogger.Info("ListOrgZone 목록 조회 결과") + cblogger.Info("ListOrgZone List Lookup Result") cblogger.Debug(result) - cblogger.Infof("로그 레벨 : [%s]", cblog.GetLevel()) + cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) //spew.Dump(result) cblogger.Info("출력 결과 수 : ", len(result)) } @@ -1736,12 +1736,12 @@ func handlePriceInfo() { case 1: result, err := handler.ListProductFamily("us-west-1") if err != nil { - cblogger.Infof("ListProductFamily 목록 조회 실패 : %s", err) + cblogger.Infof("ListProductFamily List Lookup Failed : %s", err) } else { - cblogger.Info("ListProductFamily 목록 조회 결과") + cblogger.Info("ListProductFamily List Lookup Result") // cblogger.Debugf("결과 %s", result[0]) spew.Dump(result) - cblogger.Infof("로그 레벨 : [%s]", cblog.GetLevel()) + cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) //spew.Dump(result) cblogger.Info("출력 결과 수 : ", len(result)) } @@ -1770,7 +1770,7 @@ func handlePriceInfo() { } else { cblogger.Info("GetPriceInfo 조회 결과") cblogger.Info(result) - cblogger.Infof("로그 레벨 : [%s]", cblog.GetLevel()) + cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) } } } @@ -1815,18 +1815,18 @@ func handleTag() { return case 1: - cblogger.Infof("조회 요청 태그 타입 : [%s]", reqType) + cblogger.Infof("Lookup request tag type : [%s]", reqType) if reqType == irs.VM { - cblogger.Debug("VM 요청됨") + cblogger.Debug("VM Requested") } result, err := handler.ListTag(reqType, reqIID) if err != nil { - cblogger.Info(" Tag 목록 조회 실패 : ", err) + cblogger.Info(" Tag List Lookup Failed : ", err) } else { - cblogger.Info("Tag 목록 조회 결과") + cblogger.Info("Tag List Lookup Result") cblogger.Debug(result) - cblogger.Infof("로그 레벨 : [%s]", cblog.GetLevel()) + cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) //spew.Dump(result) cblogger.Info("출력 결과 수 : ", len(result)) From 8bcbad2210e4f2898bc7251016e8e621bb76b4ec Mon Sep 17 00:00:00 2001 From: dev4unet Date: Mon, 15 Jul 2024 09:29:43 +0000 Subject: [PATCH 02/32] Edit Korean messages to English --- .../drivers/aws/main/Test_Resources.go | 383 +++++++++--------- 1 file changed, 191 insertions(+), 192 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go index 6f79a1a2d..798186302 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go @@ -89,7 +89,7 @@ func handleSecurity() { } case 2: - cblogger.Infof("[%s] Security 생성 테스트", securityName) + cblogger.Infof("[%s] Security Create Test", securityName) securityReqInfo := irs.SecurityReqInfo{ IId: irs.IID{NameId: securityName}, @@ -170,34 +170,34 @@ func handleSecurity() { result, err := handler.CreateSecurity(securityReqInfo) if err != nil { - cblogger.Infof(securityName, " Security 생성 실패 : ", err) + cblogger.Infof(securityName, " Security Create Failed : ", err) } else { - cblogger.Infof("[%s] Security 생성 결과 : [%v]", securityName, result) + cblogger.Infof("[%s] Security Create Result : [%v]", securityName, result) securityId = result.IId.SystemId spew.Dump(result) } case 3: - cblogger.Infof("[%s] Security 조회 테스트", securityId) + cblogger.Infof("[%s] Security Lookup Test", securityId) result, err := handler.GetSecurity(irs.IID{SystemId: securityId}) if err != nil { - cblogger.Infof(securityId, " Security 조회 실패 : ", err) + cblogger.Infof(securityId, " Security Lookup Failed : ", err) } else { - cblogger.Infof("[%s] Security 조회 결과 : [%v]", securityId, result) + cblogger.Infof("[%s] Security Lookup Result : [%v]", securityId, result) spew.Dump(result) } case 4: - cblogger.Infof("[%s] Security 삭제 테스트", securityId) + cblogger.Infof("[%s] Security Delete Test", securityId) result, err := handler.DeleteSecurity(irs.IID{SystemId: securityId}) if err != nil { - cblogger.Infof(securityId, " Security 삭제 실패 : ", err) + cblogger.Infof(securityId, " Security Delete Failed : ", err) } else { - cblogger.Infof("[%s] Security 삭제 결과 : [%s]", securityId, result) + cblogger.Infof("[%s] Security Delete Result : [%s]", securityId, result) } case 5: - cblogger.Infof("[%s] Security 그룹 룰 추가 테스트", securityId) + cblogger.Infof("[%s] Security Group Rule - Add Test", securityId) result, err := handler.AddRules(irs.IID{SystemId: securityId}, &[]irs.SecurityRuleInfo{ { FromPort: "80", @@ -229,13 +229,13 @@ func handleSecurity() { }, }) if err != nil { - cblogger.Infof(securityId, " Security 그룹 룰 추가 실패 : ", err) + cblogger.Infof(securityId, " Security Group Rule - Add Failed : ", err) } else { - cblogger.Infof("[%s] Security 그룹 룰 추가 결과 : [%s]", securityId, result) + cblogger.Infof("[%s] Security Group Rule - Add Result : [%s]", securityId, result) } case 6: - cblogger.Infof("[%s] Security 그룹 룰 제거 테스트", securityId) + cblogger.Infof("[%s] Security Group Rule - Delete Test", securityId) result, err := handler.RemoveRules(irs.IID{SystemId: securityId}, &[]irs.SecurityRuleInfo{ { FromPort: "80", @@ -267,9 +267,9 @@ func handleSecurity() { }, }) if err != nil { - cblogger.Infof(securityId, " Security 그룹 룰 제거 실패 : ", err) + cblogger.Infof(securityId, " Security Group Rule - Delete Failed : ", err) } else { - cblogger.Infof("[%s] Security 그룹 룰 제거 결과 : [%s]", securityId, result) + cblogger.Infof("[%s] Security Group Rule - Delete Result : [%s]", securityId, result) } } } @@ -348,9 +348,9 @@ func handleSecurityOld() { //result, err := handler.CreateSecurity(securityReqInfo) if err != nil { - cblogger.Infof("보안 그룹 조회 실패 : ", err) + cblogger.Infof("Security Group Lookup Failed : ", err) } else { - cblogger.Info("보안 그룹 조회 결과") + cblogger.Info("Security Group Lookup Result") //cblogger.Info(result) spew.Dump(result) } @@ -413,9 +413,9 @@ func handlePublicIP() { fmt.Println("Start GetPublicIP() ...") result, err := handler.GetPublicIP(reqPublicIP) if err != nil { - cblogger.Error(reqPublicIP, " PublicIP 정보 조회 실패 : ", err) + cblogger.Error(reqPublicIP, " PublicIP 정보 Lookup Failed : ", err) } else { - cblogger.Infof("PublicIP[%s] 정보 조회 결과", reqPublicIP) + cblogger.Infof("PublicIP[%s] 정보 Lookup Result", reqPublicIP) spew.Dump(result) } fmt.Println("Finish GetPublicIP()") @@ -425,9 +425,9 @@ func handlePublicIP() { reqInfo := irs.PublicIPReqInfo{Name: "mcloud-barista-eip-test"} result, err := handler.CreatePublicIP(reqInfo) if err != nil { - cblogger.Error("PublicIP 생성 실패 : ", err) + cblogger.Error("PublicIP Create Failed : ", err) } else { - cblogger.Info("PublicIP 생성 성공 ", result) + cblogger.Info("PublicIP 생성 Success ", result) spew.Dump(result) } fmt.Println("Finish CreatePublicIP()") @@ -436,12 +436,12 @@ func handlePublicIP() { fmt.Println("Start DeletePublicIP() ...") result, err := handler.DeletePublicIP(reqPublicIP) if err != nil { - cblogger.Error(reqDelIP, " PublicIP 삭제 실패 : ", err) + cblogger.Error(reqDelIP, " PublicIP Delete Failed : ", err) } else { if result { cblogger.Infof("PublicIP[%s] 삭제 완료", reqDelIP) } else { - cblogger.Errorf("PublicIP[%s] 삭제 실패", reqDelIP) + cblogger.Errorf("PublicIP[%s] Delete Failed", reqDelIP) } } fmt.Println("Finish DeletePublicIP()") @@ -491,41 +491,41 @@ func handleKeyPair() { case 1: result, err := KeyPairHandler.ListKey() if err != nil { - cblogger.Infof(" 키 페어 List Lookup Failed : ", err) + cblogger.Infof(" KeyPair List Lookup Failed : ", err) } else { - cblogger.Info("키 페어 List Lookup Result") + cblogger.Info("KeyPair List Lookup Result") //cblogger.Info(result) spew.Dump(result) } case 2: - cblogger.Infof("[%s] 키 페어 생성 테스트", keyPairName) + cblogger.Infof("[%s] KeyPair Create Test", keyPairName) keyPairReqInfo := irs.KeyPairReqInfo{ IId: irs.IID{NameId: keyPairName}, //Name: keyPairName, } result, err := KeyPairHandler.CreateKey(keyPairReqInfo) if err != nil { - cblogger.Infof(keyPairName, " 키 페어 생성 실패 : ", err) + cblogger.Infof(keyPairName, " KeyPair Create Failed : ", err) } else { - cblogger.Infof("[%s] 키 페어 생성 결과 : [%s]", keyPairName, result) + cblogger.Infof("[%s] KeyPair Create Result : [%s]", keyPairName, result) spew.Dump(result) } case 3: - cblogger.Infof("[%s] 키 페어 조회 테스트", keyPairName) + cblogger.Infof("[%s] KeyPair Lookup Test", keyPairName) result, err := KeyPairHandler.GetKey(irs.IID{SystemId: keyPairName}) if err != nil { - cblogger.Infof(keyPairName, " 키 페어 조회 실패 : ", err) + cblogger.Infof(keyPairName, " KeyPair Lookup Failed : ", err) } else { - cblogger.Infof("[%s] 키 페어 조회 결과 : [%s]", keyPairName, result) + cblogger.Infof("[%s] KeyPair Lookup Result : [%s]", keyPairName, result) } case 4: - cblogger.Infof("[%s] 키 페어 삭제 테스트", keyPairName) + cblogger.Infof("[%s] KeyPair Delete Test", keyPairName) result, err := KeyPairHandler.DeleteKey(irs.IID{SystemId: keyPairName}) if err != nil { - cblogger.Infof(keyPairName, " 키 페어 삭제 실패 : ", err) + cblogger.Infof(keyPairName, " KeyPair Delete Failed : ", err) } else { - cblogger.Infof("[%s] 키 페어 삭제 결과 : [%s]", keyPairName, result) + cblogger.Infof("[%s] KeyPair Delete Result : [%s]", keyPairName, result) } } } @@ -582,41 +582,41 @@ func handleVNetwork() { spew.Dump(result) // 내부적으로 1개만 존재함. - //조회및 삭제 테스트를 위해 리스트의 첫번째 서브넷 ID를 요청ID로 자동 갱신함. + //조회및 Delete Test를 위해 리스트의 첫번째 서브넷 ID를 요청ID로 자동 갱신함. if result != nil { reqSubnetId = result[0].IId // 조회 및 삭제를 위해 생성된 ID로 변경 } } case 2: - cblogger.Infof("[%s] VNetwork 생성 테스트", vNetworkReqInfo.IId.NameId) + cblogger.Infof("[%s] VNetwork Create Test", vNetworkReqInfo.IId.NameId) //vNetworkReqInfo := irs.VNetworkReqInfo{} result, err := VPCHandler.CreateVNetwork(vNetworkReqInfo) if err != nil { - cblogger.Infof(reqSubnetId.NameId, " VNetwork 생성 실패 : ", err) + cblogger.Infof(reqSubnetId.NameId, " VNetwork Create Failed : ", err) } else { - cblogger.Infof("VNetwork 생성 결과 : ", result) + cblogger.Infof("VNetwork Create Result : ", result) reqSubnetId = result.IId // 조회 및 삭제를 위해 생성된 ID로 변경 spew.Dump(result) } case 3: - cblogger.Infof("[%s] VNetwork 조회 테스트", reqSubnetId) + cblogger.Infof("[%s] VNetwork Lookup Test", reqSubnetId) result, err := VPCHandler.GetVNetwork(reqSubnetId) if err != nil { - cblogger.Infof("[%s] VNetwork 조회 실패 : ", reqSubnetId, err) + cblogger.Infof("[%s] VNetwork Lookup Failed : ", reqSubnetId, err) } else { - cblogger.Infof("[%s] VNetwork 조회 결과 : [%s]", reqSubnetId, result) + cblogger.Infof("[%s] VNetwork Lookup Result : [%s]", reqSubnetId, result) spew.Dump(result) } case 4: - cblogger.Infof("[%s] VNetwork 삭제 테스트", reqSubnetId) + cblogger.Infof("[%s] VNetwork Delete Test", reqSubnetId) result, err := VPCHandler.DeleteVNetwork(reqSubnetId) if err != nil { - cblogger.Infof("[%s] VNetwork 삭제 실패 : ", reqSubnetId, err) + cblogger.Infof("[%s] VNetwork Delete Failed : ", reqSubnetId, err) } else { - cblogger.Infof("[%s] VNetwork 삭제 결과 : [%s]", reqSubnetId, result) + cblogger.Infof("[%s] VNetwork Delete Result : [%s]", reqSubnetId, result) } } } @@ -697,62 +697,62 @@ func handleVPC() { spew.Dump(result) // 내부적으로 1개만 존재함. - //조회및 삭제 테스트를 위해 리스트의 첫번째 서브넷 ID를 요청ID로 자동 갱신함. + //조회및 Delete Test를 위해 리스트의 첫번째 서브넷 ID를 요청ID로 자동 갱신함. if result != nil { reqSubnetId = result[0].IId // 조회 및 삭제를 위해 생성된 ID로 변경 - subnetReqVpcInfo = reqSubnetId //Subnet 추가/삭제 테스트용 + subnetReqVpcInfo = reqSubnetId //Subnet 추가/Delete Test용 } } case 2: - cblogger.Infof("[%s] VNetwork 생성 테스트", vpcReqInfo.IId.NameId) + cblogger.Infof("[%s] VNetwork Create Test", vpcReqInfo.IId.NameId) //vpcReqInfo := irs.VPCReqInfo{} result, err := VPCHandler.CreateVPC(vpcReqInfo) if err != nil { - cblogger.Infof(reqSubnetId.NameId, " VNetwork 생성 실패 : ", err) + cblogger.Infof(reqSubnetId.NameId, " VNetwork Create Failed : ", err) } else { - cblogger.Infof("VNetwork 생성 결과 : ", result) + cblogger.Infof("VNetwork Create Result : ", result) reqSubnetId = result.IId // 조회 및 삭제를 위해 생성된 ID로 변경 spew.Dump(result) } case 3: - cblogger.Infof("[%s] VNetwork 조회 테스트", reqSubnetId) + cblogger.Infof("[%s] VNetwork Lookup Test", reqSubnetId) result, err := VPCHandler.GetVPC(reqSubnetId) if err != nil { - cblogger.Infof("[%s] VNetwork 조회 실패 : ", reqSubnetId, err) + cblogger.Infof("[%s] VNetwork Lookup Failed : ", reqSubnetId, err) } else { - cblogger.Infof("[%s] VNetwork 조회 결과 : [%s]", reqSubnetId, result) + cblogger.Infof("[%s] VNetwork Lookup Result : [%s]", reqSubnetId, result) spew.Dump(result) } case 4: - cblogger.Infof("[%s] VNetwork 삭제 테스트", reqSubnetId) + cblogger.Infof("[%s] VNetwork Delete Test", reqSubnetId) result, err := VPCHandler.DeleteVPC(reqSubnetId) if err != nil { - cblogger.Infof("[%s] VNetwork 삭제 실패 : ", reqSubnetId, err) + cblogger.Infof("[%s] VNetwork Delete Failed : ", reqSubnetId, err) } else { - cblogger.Infof("[%s] VNetwork 삭제 결과 : [%s]", reqSubnetId, result) + cblogger.Infof("[%s] VNetwork Delete Result : [%s]", reqSubnetId, result) } case 5: - cblogger.Infof("[%s] Subnet 추가 테스트", vpcReqInfo.IId.NameId) + cblogger.Infof("[%s] Subnet Add Test", vpcReqInfo.IId.NameId) result, err := VPCHandler.AddSubnet(subnetReqVpcInfo, subnetReqInfo) if err != nil { - cblogger.Infof(reqSubnetId.NameId, " VNetwork 생성 실패 : ", err) + cblogger.Infof(reqSubnetId.NameId, " VNetwork Create Failed : ", err) } else { - cblogger.Infof("VNetwork 생성 결과 : ", result) + cblogger.Infof("VNetwork Create Result : ", result) //reqSubnetId = result.IId // 조회 및 삭제를 위해 생성된 ID로 변경 spew.Dump(result) } case 6: - cblogger.Infof("[%s] Subnet 삭제 테스트", reqSubnetId.SystemId) + cblogger.Infof("[%s] Subnet Delete Test", reqSubnetId.SystemId) result, err := VPCHandler.RemoveSubnet(subnetReqVpcInfo, reqSubnetId) if err != nil { - cblogger.Infof("[%s] Subnet 삭제 실패 : ", reqSubnetId.SystemId, err) + cblogger.Infof("[%s] Subnet Delete Failed : ", reqSubnetId.SystemId, err) } else { - cblogger.Infof("[%s] Subnet 삭제 결과 : [%s]", reqSubnetId.SystemId, result) + cblogger.Infof("[%s] Subnet Delete Result : [%s]", reqSubnetId.SystemId, result) } } } @@ -804,42 +804,42 @@ func handleImage() { cblogger.Debug(result) cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) //spew.Dump(result) - cblogger.Info("출력 결과 수 : ", len(result)) + cblogger.Info("Number of output results : ", len(result)) - //조회및 삭제 테스트를 위해 리스트의 첫번째 정보의 ID를 요청ID로 자동 갱신함. + //조회및 Delete Test를 위해 리스트의 첫번째 정보의 ID를 요청ID로 자동 갱신함. if result != nil { imageReqInfo.IId = result[0].IId // 조회 및 삭제를 위해 생성된 ID로 변경 } } case 2: - cblogger.Infof("[%s] Image 생성 테스트", imageReqInfo.IId.NameId) + cblogger.Infof("[%s] Image Create Test", imageReqInfo.IId.NameId) result, err := handler.CreateImage(imageReqInfo) if err != nil { - cblogger.Infof(imageReqInfo.IId.NameId, " Image 생성 실패 : ", err) + cblogger.Infof(imageReqInfo.IId.NameId, " Image Create Failed : ", err) } else { - cblogger.Infof("Image 생성 결과 : ", result) + cblogger.Infof("Image Create Result : ", result) imageReqInfo.IId = result.IId // 조회 및 삭제를 위해 생성된 ID로 변경 spew.Dump(result) } case 3: - cblogger.Infof("[%s] Image 조회 테스트", imageReqInfo.IId) + cblogger.Infof("[%s] Image Lookup Test", imageReqInfo.IId) result, err := handler.GetImage(imageReqInfo.IId) if err != nil { - cblogger.Infof("[%s] Image 조회 실패 : ", imageReqInfo.IId.NameId, err) + cblogger.Infof("[%s] Image Lookup Failed : ", imageReqInfo.IId.NameId, err) } else { - cblogger.Infof("[%s] Image 조회 결과 : [%s]", imageReqInfo.IId.NameId, result) + cblogger.Infof("[%s] Image Lookup Result : [%s]", imageReqInfo.IId.NameId, result) spew.Dump(result) } case 4: - cblogger.Infof("[%s] Image 삭제 테스트", imageReqInfo.IId.NameId) + cblogger.Infof("[%s] Image Delete Test", imageReqInfo.IId.NameId) result, err := handler.DeleteImage(imageReqInfo.IId) if err != nil { - cblogger.Infof("[%s] Image 삭제 실패 : ", imageReqInfo.IId.NameId, err) + cblogger.Infof("[%s] Image Delete Failed : ", imageReqInfo.IId.NameId, err) } else { - cblogger.Infof("[%s] Image 삭제 결과 : [%s]", imageReqInfo.IId.NameId, result) + cblogger.Infof("[%s] Image Delete Result : [%s]", imageReqInfo.IId.NameId, result) } } } @@ -897,33 +897,33 @@ func handleVNic() { } case 2: - cblogger.Infof("[%s] VNic 생성 테스트", vNicReqInfo.Name) + cblogger.Infof("[%s] VNic Create Test", vNicReqInfo.Name) result, err := handler.CreateVNic(vNicReqInfo) if err != nil { - cblogger.Infof(reqVnicID, " VNic 생성 실패 : ", err) + cblogger.Infof(reqVnicID, " VNic Create Failed : ", err) } else { - cblogger.Infof("VNic 생성 결과 : ", result) + cblogger.Infof("VNic Create Result : ", result) reqVnicID = result.Id // 조회 및 삭제를 위해 생성된 ID로 변경 spew.Dump(result) } case 3: - cblogger.Infof("[%s] VNic 조회 테스트", reqVnicID) + cblogger.Infof("[%s] VNic Lookup Test", reqVnicID) result, err := handler.GetVNic(reqVnicID) if err != nil { - cblogger.Infof("[%s] VNic 조회 실패 : ", reqVnicID, err) + cblogger.Infof("[%s] VNic Lookup Failed : ", reqVnicID, err) } else { - cblogger.Infof("[%s] VNic 조회 결과 : [%s]", reqVnicID, result) + cblogger.Infof("[%s] VNic Lookup Result : [%s]", reqVnicID, result) spew.Dump(result) } case 4: - cblogger.Infof("[%s] VNic 삭제 테스트", reqVnicID) + cblogger.Infof("[%s] VNic Delete Test", reqVnicID) result, err := handler.DeleteVNic(reqVnicID) if err != nil { - cblogger.Infof("[%s] VNic 삭제 실패 : ", reqVnicID, err) + cblogger.Infof("[%s] VNic Delete Failed : ", reqVnicID, err) } else { - cblogger.Infof("[%s] VNic 삭제 결과 : [%s]", reqVnicID, result) + cblogger.Infof("[%s] VNic Delete Result : [%s]", reqVnicID, result) } } } @@ -934,7 +934,7 @@ func handleVNic() { func testErr() error { //return awserr.Error("") //return errors.New("") - return awserr.New("504", "찾을 수 없음", nil) + return awserr.New("504", "not found", nil) } // Test VM Lifecycle Management (Create/Suspend/Resume/Reboot/Terminate) @@ -1006,7 +1006,7 @@ func handleVM() { //panic(err) cblogger.Error(err) } else { - cblogger.Info("VM 생성 완료!!", vmInfo) + cblogger.Info("VM Created!!", vmInfo) spew.Dump(vmInfo) VmID = vmInfo.IId } @@ -1017,10 +1017,10 @@ func handleVM() { case 2: vmInfo, err := vmHandler.GetVM(VmID) if err != nil { - cblogger.Errorf("[%s] VM 정보 조회 실패", VmID) + cblogger.Errorf("[%s] VM Info Lookup Failed", VmID) cblogger.Error(err) } else { - cblogger.Infof("[%s] VM 정보 조회 결과", VmID) + cblogger.Infof("[%s] VM Info Lookup Result", VmID) cblogger.Info(vmInfo) spew.Dump(vmInfo) } @@ -1029,60 +1029,60 @@ func handleVM() { cblogger.Info("Start Suspend VM ...") result, err := vmHandler.SuspendVM(VmID) if err != nil { - cblogger.Errorf("[%s] VM Suspend 실패 - [%s]", VmID, result) + cblogger.Errorf("[%s] VM Suspend Fail - [%s]", VmID, result) cblogger.Error(err) } else { - cblogger.Infof("[%s] VM Suspend 성공 - [%s]", VmID, result) + cblogger.Infof("[%s] VM Suspend Success - [%s]", VmID, result) } case 4: cblogger.Info("Start Resume VM ...") result, err := vmHandler.ResumeVM(VmID) if err != nil { - cblogger.Errorf("[%s] VM Resume 실패 - [%s]", VmID, result) + cblogger.Errorf("[%s] VM Resume Fail - [%s]", VmID, result) cblogger.Error(err) } else { - cblogger.Infof("[%s] VM Resume 성공 - [%s]", VmID, result) + cblogger.Infof("[%s] VM Resume Success - [%s]", VmID, result) } case 5: cblogger.Info("Start Reboot VM ...") result, err := vmHandler.RebootVM(VmID) if err != nil { - cblogger.Errorf("[%s] VM Reboot 실패 - [%s]", VmID, result) + cblogger.Errorf("[%s] VM Reboot Fail - [%s]", VmID, result) cblogger.Error(err) } else { - cblogger.Infof("[%s] VM Reboot 성공 - [%s]", VmID, result) + cblogger.Infof("[%s] VM Reboot Success - [%s]", VmID, result) } case 6: cblogger.Info("Start Terminate VM ...") result, err := vmHandler.TerminateVM(VmID) if err != nil { - cblogger.Errorf("[%s] VM Terminate 실패 - [%s]", VmID, result) + cblogger.Errorf("[%s] VM Terminate Fail - [%s]", VmID, result) cblogger.Error(err) } else { - cblogger.Infof("[%s] VM Terminate 성공 - [%s]", VmID, result) + cblogger.Infof("[%s] VM Terminate Success - [%s]", VmID, result) } case 7: cblogger.Info("Start Get VM Status...") vmStatus, err := vmHandler.GetVMStatus(VmID) if err != nil { - cblogger.Errorf("[%s] VM Get Status 실패", VmID) + cblogger.Errorf("[%s] VM Get Status Fail", VmID) cblogger.Error(err) } else { - cblogger.Infof("[%s] VM Get Status 성공 : [%s]", VmID, vmStatus) + cblogger.Infof("[%s] VM Get Status Success : [%s]", VmID, vmStatus) } case 8: cblogger.Info("Start ListVMStatus ...") vmStatusInfos, err := vmHandler.ListVMStatus() if err != nil { - cblogger.Error("ListVMStatus 실패") + cblogger.Error("ListVMStatus Fail") cblogger.Error(err) } else { - cblogger.Info("ListVMStatus 성공") + cblogger.Info("ListVMStatus Success") cblogger.Info(vmStatusInfos) spew.Dump(vmStatusInfos) } @@ -1091,14 +1091,14 @@ func handleVM() { cblogger.Info("Start ListVM ...") vmList, err := vmHandler.ListVM() if err != nil { - cblogger.Error("ListVM 실패") + cblogger.Error("ListVM Fail") cblogger.Error(err) } else { - cblogger.Info("ListVM 성공") - cblogger.Info("=========== VM 목록 ================") + cblogger.Info("ListVM Success") + cblogger.Info("=========== VM List ================") cblogger.Info(vmList) spew.Dump(vmList) - cblogger.Infof("=========== VM 목록 수 : [%d] ================", len(vmList)) + cblogger.Infof("=========== VM List count : [%d] ================", len(vmList)) if len(vmList) > 0 { VmID = vmList[0].IId } @@ -1158,7 +1158,7 @@ func handleVMSpec() { cblogger.Debug("VMSpec List Lookup Result") //spew.Dump(result) cblogger.Debug(result) - cblogger.Infof("전체 목록 개수 : [%d]", len(result)) + cblogger.Infof("Total number of lists : [%d]", len(result)) } fmt.Println("Finish ListVMSpec()") @@ -1167,9 +1167,9 @@ func handleVMSpec() { fmt.Println("Start GetVMSpec() ...") result, err := handler.GetVMSpec(reqVMSpec) if err != nil { - cblogger.Error(reqVMSpec, " VMSpec 정보 조회 실패 : ", err) + cblogger.Error(reqVMSpec, " VMSpec Info Lookup Failed : ", err) } else { - cblogger.Debugf("VMSpec[%s] 정보 조회 결과", reqVMSpec) + cblogger.Debugf("VMSpec[%s] Info Lookup Result", reqVMSpec) //spew.Dump(result) cblogger.Debug(result) } @@ -1188,7 +1188,7 @@ func handleVMSpec() { //fmt.Println(result) //fmt.Println("=========================") //fmt.Println(result) - cblogger.Infof("전체 목록 개수 : [%d]", len(result)) + cblogger.Infof("Total number of lists : [%d]", len(result)) } fmt.Println("Finish ListOrgVMSpec()") @@ -1197,9 +1197,9 @@ func handleVMSpec() { fmt.Println("Start GetOrgVMSpec() ...") result, err := handler.GetOrgVMSpec(reqVMSpec) if err != nil { - cblogger.Error(reqVMSpec, " VMSpec Org 정보 조회 실패 : ", err) + cblogger.Error(reqVMSpec, " VMSpec Org Info Lookup Failed : ", err) } else { - cblogger.Debugf("VMSpec[%s] Org 정보 조회 결과", reqVMSpec) + cblogger.Debugf("VMSpec[%s] Org Info Lookup Result", reqVMSpec) //spew.Dump(result) cblogger.Debug(result) //fmt.Println(result) @@ -1289,21 +1289,21 @@ func handleNLB() { cblogger.Debug(result) cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) //spew.Dump(result) - cblogger.Info("출력 결과 수 : ", len(result)) + cblogger.Info("Number of output results : ", len(result)) - //조회및 삭제 테스트를 위해 리스트의 첫번째 정보의 ID를 요청ID로 자동 갱신함. + //조회및 Delete Test를 위해 리스트의 첫번째 정보의 ID를 요청ID로 자동 갱신함. if result != nil { nlbReqInfo.IId = result[0].IId // 조회 및 삭제를 위해 생성된 ID로 변경 } } case 2: - cblogger.Infof("[%s] NLB 생성 테스트", nlbReqInfo.IId.NameId) + cblogger.Infof("[%s] NLB Create Test", nlbReqInfo.IId.NameId) result, err := handler.CreateNLB(nlbReqInfo) if err != nil { - cblogger.Infof(nlbReqInfo.IId.NameId, " NLB 생성 실패 : ", err) + cblogger.Infof(nlbReqInfo.IId.NameId, " NLB Create Failed : ", err) } else { - cblogger.Infof("NLB 생성 성공 : ", result) + cblogger.Infof("NLB Create Success : ", result) nlbReqInfo.IId = result.IId // 조회 및 삭제를 위해 생성된 ID로 변경 if cblogger.Level.String() == "debug" { spew.Dump(result) @@ -1311,29 +1311,29 @@ func handleNLB() { } case 3: - cblogger.Infof("[%s] NLB 조회 테스트", nlbReqInfo.IId) + cblogger.Infof("[%s] NLB Lookup Test", nlbReqInfo.IId) result, err := handler.GetNLB(nlbReqInfo.IId) if err != nil { - cblogger.Infof("[%s] NLB 조회 실패 : ", nlbReqInfo.IId.NameId, err) + cblogger.Infof("[%s] NLB Lookup Failed : ", nlbReqInfo.IId.NameId, err) } else { - cblogger.Infof("[%s] NLB 조회 성공 : [%s]", nlbReqInfo.IId.NameId, result) + cblogger.Infof("[%s] NLB Lookup Success : [%s]", nlbReqInfo.IId.NameId, result) if cblogger.Level.String() == "debug" { spew.Dump(result) } } case 4: - cblogger.Infof("[%s] NLB 삭제 테스트", nlbReqInfo.IId.NameId) + cblogger.Infof("[%s] NLB Delete Test", nlbReqInfo.IId.NameId) result, err := handler.DeleteNLB(nlbReqInfo.IId) if err != nil { - cblogger.Infof("[%s] NLB 삭제 실패 : ", nlbReqInfo.IId.NameId, err) + cblogger.Infof("[%s] NLB Delete Failed : ", nlbReqInfo.IId.NameId, err) } else { - cblogger.Info("성공") - cblogger.Infof("[%s] NLB 삭제 성공 : [%s]", nlbReqInfo.IId.NameId, result) + cblogger.Info("Success") + cblogger.Infof("[%s] NLB Delete Success : [%s]", nlbReqInfo.IId.NameId, result) } case 5: - cblogger.Infof("[%s] 리스너 변경 테스트", nlbReqInfo.IId) + cblogger.Infof("[%s] Change listener Test", nlbReqInfo.IId) reqListenerInfo := irs.ListenerInfo{ Protocol: "TCP", // AWS NLB : TCP, TLS, UDP, or TCP_UDP //IP: "", @@ -1341,64 +1341,64 @@ func handleNLB() { } result, err := handler.ChangeListener(nlbReqInfo.IId, reqListenerInfo) if err != nil { - cblogger.Infof("[%s] 리스너 변경 실패 : ", nlbReqInfo.IId.NameId, err) + cblogger.Infof("[%s] Change listener Fail : ", nlbReqInfo.IId.NameId, err) } else { - cblogger.Infof("[%s] 리스너 변경 성공 : [%s]", nlbReqInfo.IId.NameId, result) + cblogger.Infof("[%s] Change listener Success : [%s]", nlbReqInfo.IId.NameId, result) if cblogger.Level.String() == "debug" { spew.Dump(result) } } case 7: - cblogger.Infof("[%s] AddVMs 테스트", nlbReqInfo.IId.NameId) + cblogger.Infof("[%s] AddVMs Test", nlbReqInfo.IId.NameId) cblogger.Info(reqAddVMs) result, err := handler.AddVMs(nlbReqInfo.IId, reqAddVMs) if err != nil { - cblogger.Infof("[%s] AddVMs 실패 : ", nlbReqInfo.IId.NameId, err) + cblogger.Infof("[%s] AddVMs Fail : ", nlbReqInfo.IId.NameId, err) } else { - cblogger.Info("성공") - cblogger.Infof("[%s] AddVMs 성공 : [%s]", nlbReqInfo.IId.NameId, result) + cblogger.Info("Success") + cblogger.Infof("[%s] AddVMs Success : [%s]", nlbReqInfo.IId.NameId, result) } case 8: - cblogger.Infof("[%s] RemoveVMs 테스트", nlbReqInfo.IId.NameId) + cblogger.Infof("[%s] RemoveVMs Test", nlbReqInfo.IId.NameId) cblogger.Info(reqRemoveVMs) result, err := handler.RemoveVMs(nlbReqInfo.IId, reqRemoveVMs) if err != nil { - cblogger.Infof("[%s] RemoveVMs 실패 : ", nlbReqInfo.IId.NameId, err) + cblogger.Infof("[%s] RemoveVMs Fail : ", nlbReqInfo.IId.NameId, err) } else { - cblogger.Info("성공") - cblogger.Infof("[%s] RemoveVMs 성공 : [%s]", nlbReqInfo.IId.NameId, result) + cblogger.Info("Success") + cblogger.Infof("[%s] RemoveVMs Success : [%s]", nlbReqInfo.IId.NameId, result) } case 9: - cblogger.Infof("[%s] GetVMGroupHealthInfo 테스트", nlbReqInfo.IId) + cblogger.Infof("[%s] GetVMGroupHealthInfo Test", nlbReqInfo.IId) result, err := handler.GetVMGroupHealthInfo(nlbReqInfo.IId) if err != nil { - cblogger.Infof("[%s] GetVMGroupHealthInfo 실패 : ", nlbReqInfo.IId.NameId, err) + cblogger.Infof("[%s] GetVMGroupHealthInfo Fail : ", nlbReqInfo.IId.NameId, err) } else { - cblogger.Infof("[%s] GetVMGroupHealthInfo 성공 : [%s]", nlbReqInfo.IId.NameId, result) + cblogger.Infof("[%s] GetVMGroupHealthInfo Success : [%s]", nlbReqInfo.IId.NameId, result) if cblogger.Level.String() == "debug" { spew.Dump(result) } } case 6: - cblogger.Infof("[%s] NLB VM Group 변경 테스트", nlbReqInfo.IId.NameId) + cblogger.Infof("[%s] NLB VM Group Change Test", nlbReqInfo.IId.NameId) result, err := handler.ChangeVMGroupInfo(nlbReqInfo.IId, irs.VMGroupInfo{ Protocol: "TCP", Port: "8080", }) if err != nil { - cblogger.Infof("[%s] NLB VM Group 변경 실패 : ", nlbReqInfo.IId.NameId, err) + cblogger.Infof("[%s] NLB VM Group Change Fail : ", nlbReqInfo.IId.NameId, err) } else { - cblogger.Infof("[%s] NLB VM Group 변경 성공 : [%s]", nlbReqInfo.IId.NameId, result) + cblogger.Infof("[%s] NLB VM Group Change Success : [%s]", nlbReqInfo.IId.NameId, result) if cblogger.Level.String() == "debug" { spew.Dump(result) } } case 10: - cblogger.Infof("[%s] NLB Health Checker 변경 테스트", nlbReqInfo.IId.NameId) + cblogger.Infof("[%s] NLB Health Checker Change Test", nlbReqInfo.IId.NameId) result, err := handler.ChangeHealthCheckerInfo(nlbReqInfo.IId, irs.HealthCheckerInfo{ Protocol: "TCP", Port: "22", @@ -1407,9 +1407,9 @@ func handleNLB() { Threshold: 5, }) if err != nil { - cblogger.Infof("[%s] NLB Health Checker 변경 실패 : ", nlbReqInfo.IId.NameId, err) + cblogger.Infof("[%s] NLB Health Checker Change Fail : ", nlbReqInfo.IId.NameId, err) } else { - cblogger.Infof("[%s] NLB Health Checker 변경 성공 : [%s]", nlbReqInfo.IId.NameId, result) + cblogger.Infof("[%s] NLB Health Checker Change Success : [%s]", nlbReqInfo.IId.NameId, result) if cblogger.Level.String() == "debug" { spew.Dump(result) } @@ -1503,21 +1503,21 @@ func handleCluster() { cblogger.Debug(result) cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) //spew.Dump(result) - cblogger.Info("출력 결과 수 : ", len(result)) + cblogger.Info("Number of output results : ", len(result)) //조회및 삭제 테스트를 위해 리스트의 첫번째 정보의 ID를 요청ID로 자동 갱신함. if len(result) > 0 { clusterReqInfo.IId = result[0].IId // 조회 및 삭제를 위해 생성된 ID로 변경 - cblogger.Info("---> Req IID 변경 : ", clusterReqInfo.IId) + cblogger.Info("---> Req IID Change : ", clusterReqInfo.IId) } } case 2: - cblogger.Infof("[%s] Cluster Create 테스트", clusterReqInfo.IId.NameId) + cblogger.Infof("[%s] Cluster Create Test", clusterReqInfo.IId.NameId) result, err := handler.CreateCluster(clusterReqInfo) if err != nil { - cblogger.Infof(clusterReqInfo.IId.NameId, " Cluster Create 실패 : ", err) + cblogger.Infof(clusterReqInfo.IId.NameId, " Cluster Create Fail : ", err) } else { - cblogger.Infof("Cluster Create 성공 : ", result) + cblogger.Infof("Cluster Create Success : ", result) clusterReqInfo.IId = result.IId // 조회 및 삭제를 위해 생성된 ID로 변경 if cblogger.Level.String() == "debug" { spew.Dump(result) @@ -1527,42 +1527,42 @@ func handleCluster() { //eks-cb-eks-node-test02a-aws-9cc2876a-d3cb-2c25-55a8-9a19c431e716 case 3: - cblogger.Infof("[%s] Cluster Get 테스트", clusterReqInfo.IId) + cblogger.Infof("[%s] Cluster Get Test", clusterReqInfo.IId) result, err := handler.GetCluster(clusterReqInfo.IId) if err != nil { - cblogger.Infof("[%s] Cluster Get 실패 : ", clusterReqInfo.IId.NameId, err) + cblogger.Infof("[%s] Cluster Get Fail : ", clusterReqInfo.IId.NameId, err) } else { - cblogger.Infof("[%s] Cluster Get 성공 : [%s]", clusterReqInfo.IId.NameId, result) + cblogger.Infof("[%s] Cluster Get Success : [%s]", clusterReqInfo.IId.NameId, result) if cblogger.Level.String() == "debug" { spew.Dump(result) } } case 4: - cblogger.Infof("[%s] Cluster Delete 테스트", clusterReqInfo.IId.NameId) + cblogger.Infof("[%s] Cluster Delete Test", clusterReqInfo.IId.NameId) result, err := handler.DeleteCluster(clusterReqInfo.IId) if err != nil { - cblogger.Infof("[%s] Cluster Delete 실패 : ", clusterReqInfo.IId.NameId, err) + cblogger.Infof("[%s] Cluster Delete Fail : ", clusterReqInfo.IId.NameId, err) } else { - cblogger.Info("성공") - cblogger.Infof("[%s] Cluster Delete 성공 : [%s]", clusterReqInfo.IId.NameId, result) + cblogger.Info("Success") + cblogger.Infof("[%s] Cluster Delete Success : [%s]", clusterReqInfo.IId.NameId, result) } /* case 5: - cblogger.Infof("[%s] ListNodeGroup 테스트", clusterReqInfo.IId) + cblogger.Infof("[%s] ListNodeGroup Test", clusterReqInfo.IId) result, err := handler.ListNodeGroup(clusterReqInfo.IId) if err != nil { - cblogger.Infof("[%s] ListNodeGroup 실패 : ", clusterReqInfo.IId.NameId, err) + cblogger.Infof("[%s] ListNodeGroup Fail : ", clusterReqInfo.IId.NameId, err) } else { - cblogger.Infof("[%s] ListNodeGroup 성공 : [%s]", clusterReqInfo.IId.NameId, result) + cblogger.Infof("[%s] ListNodeGroup Success : [%s]", clusterReqInfo.IId.NameId, result) if cblogger.Level.String() == "debug" { spew.Dump(result) } - cblogger.Info("출력 결과 수 : ", len(result)) + cblogger.Info("Number of output results : ", len(result)) - //조회및 삭제 테스트를 위해 리스트의 첫번째 정보의 ID를 요청ID로 자동 갱신함. + //조회및 삭제 Test를 위해 리스트의 첫번째 정보의 ID를 요청ID로 자동 갱신함. if len(result) > 0 { reqNodeGroupInfo.IId = result[0].IId // 조회 및 삭제를 위해 생성된 ID로 변경 cblogger.Info("---> Req IID 변경 : ", reqNodeGroupInfo.IId) @@ -1571,49 +1571,49 @@ func handleCluster() { */ case 6: - cblogger.Infof("[%s] AddNodeGroup 테스트", clusterReqInfo.IId) + cblogger.Infof("[%s] AddNodeGroup Test", clusterReqInfo.IId) result, err := handler.AddNodeGroup(clusterReqInfo.IId, reqNodeGroupInfo) if err != nil { - cblogger.Infof("[%s] AddNodeGroup 실패 : ", clusterReqInfo.IId.NameId, err) + cblogger.Infof("[%s] AddNodeGroup Fail : ", clusterReqInfo.IId.NameId, err) } else { - cblogger.Infof("[%s] AddNodeGroup 성공 : [%s]", clusterReqInfo.IId.NameId, result) + cblogger.Infof("[%s] AddNodeGroup Success : [%s]", clusterReqInfo.IId.NameId, result) if cblogger.Level.String() == "debug" { spew.Dump(result) } } case 7: - cblogger.Infof("[%s] RemoveNodeGroup 테스트", clusterReqInfo.IId) + cblogger.Infof("[%s] RemoveNodeGroup Test", clusterReqInfo.IId) result, err := handler.RemoveNodeGroup(clusterReqInfo.IId, reqNodeGroupInfo.IId) if err != nil { - cblogger.Infof("[%s] RemoveNodeGroup 실패 : ", reqNodeGroupInfo.IId.SystemId, err) + cblogger.Infof("[%s] RemoveNodeGroup Fail : ", reqNodeGroupInfo.IId.SystemId, err) } else { - cblogger.Infof("[%s] RemoveNodeGroup 성공", reqNodeGroupInfo.IId.SystemId) + cblogger.Infof("[%s] RemoveNodeGroup Success", reqNodeGroupInfo.IId.SystemId) if cblogger.Level.String() == "debug" { spew.Dump(result) } } case 8: - cblogger.Infof("[%s] UpgradeCluster 테스트", clusterReqInfo.IId) + cblogger.Infof("[%s] UpgradeCluster Test", clusterReqInfo.IId) result, err := handler.UpgradeCluster(clusterReqInfo.IId, "1.24") if err != nil { - cblogger.Infof("[%s] UpgradeCluster 실패 : ", clusterReqInfo.IId.NameId, err) + cblogger.Infof("[%s] UpgradeCluster Fail : ", clusterReqInfo.IId.NameId, err) } else { - cblogger.Infof("[%s] UpgradeCluster 성공 : [%s]", clusterReqInfo.IId.NameId, result) + cblogger.Infof("[%s] UpgradeCluster Success : [%s]", clusterReqInfo.IId.NameId, result) if cblogger.Level.String() == "debug" { spew.Dump(result) } } case 9: - cblogger.Infof("[%s] ChangeNodeGroupScaling 테스트", clusterReqInfo.IId) + cblogger.Infof("[%s] ChangeNodeGroupScaling Test", clusterReqInfo.IId) //원하는 크기 / 최소 크기 / 최대 크기 result, err := handler.ChangeNodeGroupScaling(clusterReqInfo.IId, reqNodeGroupInfo.IId, 2, 2, 4) if err != nil { - cblogger.Infof("[%s] ChangeNodeGroupScaling 실패 : ", clusterReqInfo.IId.NameId, err) + cblogger.Infof("[%s] ChangeNodeGroupScaling Fail : ", clusterReqInfo.IId.NameId, err) } else { - cblogger.Infof("[%s] ChangeNodeGroupScaling 성공 : [%s]", clusterReqInfo.IId.NameId, result) + cblogger.Infof("[%s] ChangeNodeGroupScaling Success : [%s]", clusterReqInfo.IId.NameId, result) if cblogger.Level.String() == "debug" { spew.Dump(result) } @@ -1664,15 +1664,15 @@ func handleRegionZone() { spew.Dump(result) cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) //spew.Dump(result) - cblogger.Info("출력 결과 수 : ", len(result)) + cblogger.Info("Number of output results : ", len(result)) } case 2: result, err := handler.GetRegionZone("us-west-1") if err != nil { - cblogger.Infof("GetRegionZone 조회 실패 : ", err) + cblogger.Infof("GetRegionZone Lookup Failed : ", err) } else { - cblogger.Info("GetRegionZone 조회 결과") + cblogger.Info("GetRegionZone Lookup Result") cblogger.Debug(result) cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) // spew.Dump(result) @@ -1687,7 +1687,7 @@ func handleRegionZone() { cblogger.Debug(result) cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) //spew.Dump(result) - cblogger.Info("출력 결과 수 : ", len(result)) + cblogger.Info("Number of output results : ", len(result)) } case 4: result, err := handler.ListOrgZone() @@ -1698,7 +1698,7 @@ func handleRegionZone() { cblogger.Debug(result) cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) //spew.Dump(result) - cblogger.Info("출력 결과 수 : ", len(result)) + cblogger.Info("Number of output results : ", len(result)) } } } @@ -1743,7 +1743,7 @@ func handlePriceInfo() { spew.Dump(result) cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) //spew.Dump(result) - cblogger.Info("출력 결과 수 : ", len(result)) + cblogger.Info("Number of output results : ", len(result)) } case 2: @@ -1766,9 +1766,9 @@ func handlePriceInfo() { result, err := handler.GetPriceInfo("Compute Instance", "us-west-1", filterList) if err != nil { - cblogger.Infof("GetPriceInfo 조회 실패 : ", err) + cblogger.Infof("GetPriceInfo Lookup Failed : ", err) } else { - cblogger.Info("GetPriceInfo 조회 결과") + cblogger.Info("GetPriceInfo Lookup Result") cblogger.Info(result) cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) } @@ -1789,7 +1789,7 @@ func handleTag() { var reqType irs.RSType = irs.VM reqIID := irs.IID{SystemId: "i-02ac1c4ff1d40815c"} - reqTag := irs.KeyValue{Key: "tag3", Value: "태그3"} + reqTag := irs.KeyValue{Key: "tag3", Value: "tag3 test"} reqKey := "tag3" reqKey = "" reqType = irs.ALL @@ -1828,7 +1828,7 @@ func handleTag() { cblogger.Debug(result) cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) //spew.Dump(result) - cblogger.Info("출력 결과 수 : ", len(result)) + cblogger.Info("Number of output results : ", len(result)) //조회및 삭제 테스트를 위해 리스트의 첫번째 정보의 ID를 요청ID로 자동 갱신함. if result != nil { @@ -1837,45 +1837,44 @@ func handleTag() { } case 2: - cblogger.Infof("[%s] Tag 추가 테스트", reqIID.SystemId) + cblogger.Infof("[%s] Tag Add Test", reqIID.SystemId) result, err := handler.AddTag(reqType, reqIID, reqTag) if err != nil { - cblogger.Infof(reqIID.SystemId, " Tag 생성 실패 : ", err) + cblogger.Infof(reqIID.SystemId, " Tag Create Failed : ", err) } else { - cblogger.Info("Tag 생성 결과 : ", result) + cblogger.Info("Tag Create Result : ", result) reqKey = result.Key - cblogger.Infof("요청 대상 Tag Key가 [%s]로 변경 됨", reqKey) + cblogger.Infof("Request Target Tag Key changed to [%s]", reqKey) spew.Dump(result) } case 3: - cblogger.Infof("[%s] Tag 조회 테스트 - Key[%s]", reqIID.SystemId, reqKey) + cblogger.Infof("[%s] Tag Lookup Test - Key[%s]", reqIID.SystemId, reqKey) result, err := handler.GetTag(reqType, reqIID, reqKey) if err != nil { - cblogger.Infof("[%s] Tag 조회 실패 : [%v]", reqKey, err) + cblogger.Infof("[%s] Tag Lookup Failed : [%v]", reqKey, err) } else { - cblogger.Infof("[%s] Tag 조회 결과 : [%s]", reqKey, result) + cblogger.Infof("[%s] Tag Lookup Result : [%s]", reqKey, result) spew.Dump(result) } case 4: - cblogger.Infof("[%s] Tag 삭제 테스트 - Key[%s]", reqIID.SystemId, reqKey) + cblogger.Infof("[%s] Tag Delete Test - Key[%s]", reqIID.SystemId, reqKey) result, err := handler.RemoveTag(reqType, reqIID, reqKey) if err != nil { - cblogger.Infof("[%s] Tag 삭제 실패 : [%v]", reqKey, err) + cblogger.Infof("[%s] Tag Delete Failed : [%v]", reqKey, err) } else { - cblogger.Infof("[%s] Tag 삭제 결과 : [%v]", reqKey, result) + cblogger.Infof("[%s] Tag Delete Result : [%v]", reqKey, result) } case 5: - cblogger.Infof("[%s] Tag 찾기 테스트 - Key[%s]", reqType, reqKey) + cblogger.Infof("[%s] Tag Find Test - Key[%s]", reqType, reqKey) result, err := handler.FindTag(reqType, reqKey) if err != nil { - cblogger.Infof("[%s] Tag 검색 실패 : [%s]", reqKey, err) + cblogger.Infof("[%s] Tag Find Failed : [%s]", reqKey, err) } else { - cblogger.Infof("[%s] Tag 검색 결과 : [%d]건", reqKey, len(result)) spew.Dump(result) - cblogger.Infof("Tag 검색 결과 : [%d]건", len(result)) + cblogger.Infof("[%s] Tag Find Result : [%d] count", reqKey, len(result)) } } } From 88897cfdb2b0797f040d025e2c0dafc5502a3363 Mon Sep 17 00:00:00 2001 From: innodreamer Date: Tue, 16 Jul 2024 17:02:22 +0900 Subject: [PATCH 03/32] Change cblogger.Error to cblogger.Debug --- .../cloud-driver/drivers/ncpvpc/resources/VPCHandler.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/ncpvpc/resources/VPCHandler.go b/cloud-control-manager/cloud-driver/drivers/ncpvpc/resources/VPCHandler.go index fa72f493a..c00b5acc6 100644 --- a/cloud-control-manager/cloud-driver/drivers/ncpvpc/resources/VPCHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ncpvpc/resources/VPCHandler.go @@ -366,7 +366,7 @@ func (vpcHandler *NcpVpcVPCHandler) DeleteVPC(vpcIID irs.IID) (bool, error) { subnetStatus, err := vpcHandler.WaitForDeleteSubnet(vpcIID.SystemId, lastSubentIID) if err != nil { newErr := fmt.Errorf("Failed to Wait for Subnet Deletion : [%v]", err) - cblogger.Error(newErr.Error()) + cblogger.Debug(newErr.Error()) // For Termination Completion of a Subnet LoggingError(callLogInfo, newErr) // return false, newErr } @@ -611,7 +611,7 @@ func (vpcHandler *NcpVpcVPCHandler) GetNcpSubnetInfo(sunbnetId *string) (*vpc.Su if len(result.SubnetList) < 1 { newErr := fmt.Errorf("Failed to Get any Subnet Info with the ID!!") - cblogger.Error(newErr.Error()) + cblogger.Debug(newErr.Error()) // For Termination Completion of a Subnet LoggingError(callLogInfo, newErr) return nil, newErr } else { @@ -843,7 +843,7 @@ func (vpcHandler *NcpVpcVPCHandler) WaitForDeleteSubnet(vpcNo string, subnetIID ncpSubnetInfo, getErr := vpcHandler.GetNcpSubnetInfo(&subnetIID.SystemId) if getErr != nil { newErr := fmt.Errorf("Failed to Get the Subnet Info : [%v]", getErr) - cblogger.Error(newErr.Error()) + cblogger.Debug(newErr.Error()) // For Termination Completion of a Subnet return "", newErr } else { cblogger.Infof("Succeeded in Getting the Subnet Info of [%s]", subnetIID.SystemId) From 9d8fc09b92c242159eda2430accc8a67a878005c Mon Sep 17 00:00:00 2001 From: innodreamer Date: Tue, 16 Jul 2024 17:09:10 +0900 Subject: [PATCH 04/32] Remove Unnecessary Parameter on RegionZoneHandler (NCP VPC) --- .../cloud-driver/drivers/ncpvpc/resources/RegionZoneHandler.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cloud-control-manager/cloud-driver/drivers/ncpvpc/resources/RegionZoneHandler.go b/cloud-control-manager/cloud-driver/drivers/ncpvpc/resources/RegionZoneHandler.go index 4f0a3107c..288851f9d 100644 --- a/cloud-control-manager/cloud-driver/drivers/ncpvpc/resources/RegionZoneHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ncpvpc/resources/RegionZoneHandler.go @@ -27,7 +27,6 @@ import ( ) type NcpRegionZoneHandler struct { - CredentialInfo idrv.CredentialInfo RegionInfo idrv.RegionInfo VMClient *vserver.APIClient } From c52d140de895112fe1f6b9a3c564b8bc35651354 Mon Sep 17 00:00:00 2001 From: innodreamer Date: Tue, 16 Jul 2024 17:13:56 +0900 Subject: [PATCH 05/32] Update for VM Status check when running GetVM(), ListVM() --- .../drivers/ncp/resources/VMHandler.go | 38 ++++++++----------- .../drivers/ncpvpc/resources/VMHandler.go | 38 ++++++++----------- 2 files changed, 32 insertions(+), 44 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/ncp/resources/VMHandler.go b/cloud-control-manager/cloud-driver/drivers/ncp/resources/VMHandler.go index 433dd0524..5cf94d903 100644 --- a/cloud-control-manager/cloud-driver/drivers/ncp/resources/VMHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ncp/resources/VMHandler.go @@ -533,11 +533,11 @@ func (vmHandler *NcpVMHandler) GetVM(vmIID irs.IID) (irs.VMInfo, error) { // Since it's impossible to get VM info. during Creation, ... switch string(curStatus) { - case "Creating", "Booting": + case "Creating": cblogger.Infof("Wait for the VM creation before inquiring VM info. The VM status : [%s]", string(curStatus)) - return irs.VMInfo{}, errors.New("The VM status is 'Creating' or 'Booting', wait for the VM creation before inquiring VM info. : " + vmIID.SystemId) + return irs.VMInfo{}, errors.New("The VM status is 'Creating', wait for the VM creation before inquiring VM info. : " + vmIID.SystemId) default: - cblogger.Infof("===> The VM status not 'Creating' or 'Booting', you can get the VM info.") + cblogger.Infof("===> The VM status not 'Creating', you can get the VM info.") } regionNo, err := vmHandler.GetRegionNo(vmHandler.RegionInfo.Region) @@ -969,7 +969,7 @@ func ConvertVMStatusString(vmStatus string) (irs.VMStatus, error) { //Caution!! resultStatus = "Booting" } else if strings.EqualFold(vmStatus, "setting up") { - resultStatus = "Creating" + resultStatus = "Setting_up" } else if strings.EqualFold(vmStatus, "running") { resultStatus = "Running" } else if strings.EqualFold(vmStatus, "shutting down") { @@ -1136,29 +1136,23 @@ func (vmHandler *NcpVMHandler) ListVM() ([]*irs.VMInfo, error) { cblogger.Debug(newErr.Error()) return nil, nil // Not returns Error message } else { - cblogger.Info("Succeeded in Getting ServerInstanceList!!") + cblogger.Info("Succeeded in Getting ServerInstanceList from NCP!!") } var vmInfoList []*irs.VMInfo for _, vm := range result.ServerInstanceList { - cblogger.Info("NCP VM Instance Info. inquiry : ", *vm.ServerInstanceNo) - - curStatus, errStatus := vmHandler.GetVMStatus(irs.IID{SystemId: *vm.ServerInstanceNo}) - if errStatus != nil { - rtnErr := logAndReturnError(callLogInfo, "Failed to Get the VM Status : ", errStatus) - return nil, rtnErr + curStatus, statusErr := vmHandler.GetVMStatus(irs.IID{SystemId: *vm.ServerInstanceNo}) + if statusErr != nil { + newErr := fmt.Errorf("Failed to Get the Status of VM : [%s], [%v]", *vm.ServerInstanceNo, statusErr.Error()) + cblogger.Error(newErr.Error()) + return nil, newErr } else { - cblogger.Infof("Succeeded to Get the VM Status of [%s] : [%s]", irs.IID{SystemId: *vm.ServerInstanceNo}, curStatus) + cblogger.Infof("Succeeded to Get the Status of VM [%s] : [%s]", *vm.ServerInstanceNo, string(curStatus)) } - cblogger.Info("===> VM Status : ", curStatus) + cblogger.Infof("===> VM Status : [%s]", string(curStatus)) - switch string(curStatus) { - case "Creating", "Booting": - cblogger.Errorf("The VM status : [%s], Can Not Get the VM info.", string(curStatus)) - return nil, nil - - default: - cblogger.Infof("===> The VM status not 'Creating' or 'Booting', you can get the VM info.") + if (string(curStatus) != "Creating") && (string(curStatus) != "Terminating") { + cblogger.Infof("===> The VM Status not 'Creating' or 'Terminating', you can get the VM info.") vmInfo, error := vmHandler.GetVM(irs.IID{SystemId: *vm.ServerInstanceNo}) if error != nil { cblogger.Error(error.Error()) @@ -1189,9 +1183,9 @@ func (vmHandler *NcpVMHandler) WaitToGetInfo(vmIID irs.IID) (irs.VMStatus, error cblogger.Infof("===> VM Status : [%s]", curStatus) switch string(curStatus) { - case "Creating", "Booting": + case "Creating", "Booting", "Setting_up": curRetryCnt++ - cblogger.Infof("The VM is still 'Creating', so wait for a second more before inquiring the VM info.") + cblogger.Infof("The VM is still 'Creating' and 'Booting', so wait for a second more before inquiring the VM info.") time.Sleep(time.Second * 5) if curRetryCnt > maxRetryCnt { cblogger.Errorf("Despite waiting for a long time(%d sec), the VM status is %s, so it is forcibly finishied.", maxRetryCnt, curStatus) diff --git a/cloud-control-manager/cloud-driver/drivers/ncpvpc/resources/VMHandler.go b/cloud-control-manager/cloud-driver/drivers/ncpvpc/resources/VMHandler.go index 5db0e66d5..e5d0d6e8c 100644 --- a/cloud-control-manager/cloud-driver/drivers/ncpvpc/resources/VMHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ncpvpc/resources/VMHandler.go @@ -62,7 +62,7 @@ func init() { func (vmHandler *NcpVpcVMHandler) StartVM(vmReqInfo irs.VMReqInfo) (irs.VMInfo, error) { cblogger.Info("NCPVPC Cloud driver: called StartVM()!!") InitLog() - callLogInfo := GetCallLogScheme(vmHandler.CredentialInfo.ClientId, call.VM, vmReqInfo.IId.NameId, "StartVM()") + callLogInfo := GetCallLogScheme(vmHandler.RegionInfo.Region, call.VM, vmReqInfo.IId.NameId, "StartVM()") if strings.EqualFold(vmReqInfo.IId.NameId, "") { newErr := fmt.Errorf("Invalid VM Name required") @@ -334,11 +334,11 @@ func (vmHandler *NcpVpcVMHandler) GetVM(vmIID irs.IID) (irs.VMInfo, error) { // Since it's impossible to get VM info. during Creation, ... switch string(curStatus) { - case "Creating", "Booting": + case "Creating": cblogger.Infof("The VM status is '%s', so wait for the VM creation before inquiring the info.", string(curStatus)) - return irs.VMInfo{}, errors.New("The VM status is 'Creating' or 'Booting', so wait for the VM creation before inquiring the info. : " + vmIID.SystemId) + return irs.VMInfo{}, errors.New("The VM status is 'Creating', so wait for the VM creation before inquiring the info. : " + vmIID.SystemId) default: - cblogger.Infof("===> The VM status is not 'Creating' or 'Booting', you can get the VM info.") + cblogger.Infof("===> The VM status is not 'Creating', you can get the VM info.") } /* @@ -776,7 +776,7 @@ func ConvertVMStatusString(vmStatus string) (irs.VMStatus, error) { //Caution!! resultStatus = "Booting" } else if strings.EqualFold(vmStatus, "setting up") { - resultStatus = "Creating" + resultStatus = "Setting_up" } else if strings.EqualFold(vmStatus, "running") { resultStatus = "Running" } else if strings.EqualFold(vmStatus, "shutting down") { @@ -901,36 +901,30 @@ func (vmHandler *NcpVpcVMHandler) ListVM() ([]*irs.VMInfo, error) { return nil, newErr } LoggingInfo(callLogInfo, callLogStart) - cblogger.Info("Succeeded in Getting ServerInstanceList from NCP VPC!!") + cblogger.Info("Succeeded in Getting ServerInstanceList from NCP!!") var vmInfoList []*irs.VMInfo for _, vm := range result.ServerInstanceList { - cblogger.Infof("Inquiry of NCP VM Instance info : [%s]", *vm.ServerInstanceNo) - curStatus, statusErr := vmHandler.GetVMStatus(irs.IID{SystemId: *vm.ServerInstanceNo}) if statusErr != nil { - cblogger.Errorf("Failed to Get the VM Status of VM : [%s]", *vm.ServerInstanceNo) - cblogger.Error(statusErr.Error()) + newErr := fmt.Errorf("Failed to Get the Status of VM : [%s], [%v]", *vm.ServerInstanceNo, statusErr.Error()) + cblogger.Error(newErr.Error()) + return nil, newErr } else { - cblogger.Infof("Succeed in Getting the VM Status of [%s] : [%s]", *vm.ServerInstanceNo, curStatus) + cblogger.Infof("Succeeded in Getting the Status of VM [%s] : [%s]", *vm.ServerInstanceNo, string(curStatus)) } - cblogger.Infof("===> VM Status : [%s]", curStatus) - - switch string(curStatus) { - case "Creating", "Booting": - return []*irs.VMInfo{}, nil + cblogger.Infof("===> VM Status : [%s]", string(curStatus)) - default: - cblogger.Infof("===> The VM status not 'Creating' or 'Booting', you can get the VM info.") + if (string(curStatus) != "Creating") && (string(curStatus) != "Terminating") { + cblogger.Infof("===> The VM Status not 'Creating' or 'Terminating', you can get the VM info.") vmInfo, error := vmHandler.GetVM(irs.IID{SystemId: *vm.ServerInstanceNo}) if error != nil { cblogger.Error(error.Error()) - return []*irs.VMInfo{}, error + return nil, error } vmInfoList = append(vmInfoList, &vmInfo) } } - return vmInfoList, nil } @@ -1349,9 +1343,9 @@ func (vmHandler *NcpVpcVMHandler) WaitToGetInfo(vmIID irs.IID) (irs.VMStatus, er cblogger.Infof("===> VM Status : [%s]", curStatus) switch string(curStatus) { - case "Creating", "Booting": + case "Creating", "Booting", "Setting_up": curRetryCnt++ - cblogger.Infof("The VM is 'Creating', so wait for a second more before inquiring the VM info.") + cblogger.Infof("The VM is 'Creating' and 'Booting', so wait for a second more before inquiring the VM info.") time.Sleep(time.Second * 5) if curRetryCnt > maxRetryCnt { cblogger.Errorf("Despite waiting for a long time(%d sec), the VM status is '%s', so it is forcibly finishied.", maxRetryCnt, curStatus) From 7dc385e4fe3062c6929f97a01eb4f30f967fed35 Mon Sep 17 00:00:00 2001 From: innodreamer Date: Tue, 16 Jul 2024 17:17:38 +0900 Subject: [PATCH 06/32] Update drvCapabilityInfo --- .../cloud-driver/drivers/ncp/NcpDriver.go | 14 ++++++++++---- .../cloud-driver/drivers/ncpvpc/NcpVpcDriver.go | 13 +++++++++---- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/ncp/NcpDriver.go b/cloud-control-manager/cloud-driver/drivers/ncp/NcpDriver.go index a95af3481..419574fa4 100644 --- a/cloud-control-manager/cloud-driver/drivers/ncp/NcpDriver.go +++ b/cloud-control-manager/cloud-driver/drivers/ncp/NcpDriver.go @@ -46,14 +46,20 @@ func (NcpDriver) GetDriverCapability() idrv.DriverCapabilityInfo { var drvCapabilityInfo idrv.DriverCapabilityInfo // NOTE Temporary Setting - drvCapabilityInfo.ImageHandler = true drvCapabilityInfo.VPCHandler = true - drvCapabilityInfo.SecurityHandler = true - drvCapabilityInfo.KeyPairHandler = true drvCapabilityInfo.VNicHandler = false + drvCapabilityInfo.ImageHandler = true + drvCapabilityInfo.VMSpecHandler = true + drvCapabilityInfo.SecurityHandler = true + drvCapabilityInfo.KeyPairHandler = true drvCapabilityInfo.PublicIPHandler = false drvCapabilityInfo.VMHandler = true - drvCapabilityInfo.VMSpecHandler = true + drvCapabilityInfo.DiskHandler = true + drvCapabilityInfo.MyImageHandler = true + drvCapabilityInfo.NLBHandler = true + drvCapabilityInfo.PriceInfoHandler = true + drvCapabilityInfo.RegionZoneHandler = true + drvCapabilityInfo.TagHandler = true return drvCapabilityInfo } diff --git a/cloud-control-manager/cloud-driver/drivers/ncpvpc/NcpVpcDriver.go b/cloud-control-manager/cloud-driver/drivers/ncpvpc/NcpVpcDriver.go index 72f444780..1542c82ad 100644 --- a/cloud-control-manager/cloud-driver/drivers/ncpvpc/NcpVpcDriver.go +++ b/cloud-control-manager/cloud-driver/drivers/ncpvpc/NcpVpcDriver.go @@ -46,15 +46,20 @@ func (NcpVpcDriver) GetDriverCapability() idrv.DriverCapabilityInfo { var drvCapabilityInfo idrv.DriverCapabilityInfo // NOTE Temporary Setting - drvCapabilityInfo.ImageHandler = true drvCapabilityInfo.VPCHandler = true - drvCapabilityInfo.SecurityHandler = true - drvCapabilityInfo.KeyPairHandler = true drvCapabilityInfo.VNicHandler = false + drvCapabilityInfo.ImageHandler = true + drvCapabilityInfo.VMSpecHandler = true + drvCapabilityInfo.SecurityHandler = true + drvCapabilityInfo.KeyPairHandler = true drvCapabilityInfo.PublicIPHandler = false drvCapabilityInfo.VMHandler = true - drvCapabilityInfo.VMSpecHandler = true + drvCapabilityInfo.DiskHandler = true + drvCapabilityInfo.MyImageHandler = true drvCapabilityInfo.NLBHandler = true + drvCapabilityInfo.PriceInfoHandler = true + drvCapabilityInfo.RegionZoneHandler = true + drvCapabilityInfo.TagHandler = false return drvCapabilityInfo } From 6847687e6305d593c28a796d14dd9b964de6ee4c Mon Sep 17 00:00:00 2001 From: innodreamer Date: Tue, 16 Jul 2024 17:18:46 +0900 Subject: [PATCH 07/32] Remove the Duplicate Codes --- .../drivers/ncp-plugin/NcpDriver-lib.go | 99 +------------- .../drivers/ncpvpc-plugin/NcpVpcDriver-lib.go | 124 +----------------- 2 files changed, 8 insertions(+), 215 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/ncp-plugin/NcpDriver-lib.go b/cloud-control-manager/cloud-driver/drivers/ncp-plugin/NcpDriver-lib.go index 030afd1c8..828af5ab8 100644 --- a/cloud-control-manager/cloud-driver/drivers/ncp-plugin/NcpDriver-lib.go +++ b/cloud-control-manager/cloud-driver/drivers/ncp-plugin/NcpDriver-lib.go @@ -7,104 +7,13 @@ // This is a Cloud Driver Example for PoC Test. // // by ETRI, 2020.08. +// by ETRI, 2024.07. package main import ( - //cblog "github.com/cloud-barista/cb-log" - - idrv "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces" - icon "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces/connect" - - // "github.com/davecgh/go-spew/spew" - // unused import "github.com/sirupsen/logrus" - - ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go-v2/ncloud" - server "github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/server" - lb "github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/loadbalancer" - - // ncpcon "github.com/cloud-barista/ncp/ncp/connect" - ncpcon "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/drivers/ncp/connect" //To be built in the container + "C" + ncp "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/drivers/ncp" ) -/* -var cblogger *logrus.Logger - -func init() { - // cblog is a global variable. - cblogger = cblog.GetLogger("NCP VMHandler") -} -*/ - -type NcpDriver struct { -} - -func (NcpDriver) GetDriverVersion() string { - return "TEST NCP DRIVER Version 1.0" -} - -func (NcpDriver) GetDriverCapability() idrv.DriverCapabilityInfo { - var drvCapabilityInfo idrv.DriverCapabilityInfo - - // NOTE Temporary Setting - drvCapabilityInfo.ImageHandler = true - drvCapabilityInfo.VPCHandler = true - drvCapabilityInfo.SecurityHandler = true - drvCapabilityInfo.KeyPairHandler = true - drvCapabilityInfo.VNicHandler = false - drvCapabilityInfo.PublicIPHandler = false - drvCapabilityInfo.VMHandler = true - drvCapabilityInfo.VMSpecHandler = true - - return drvCapabilityInfo -} - -// func getVMClient(credential idrv.CredentialInfo) (*server.APIClient, error) { -func getVMClient(connectionInfo idrv.ConnectionInfo) (*server.APIClient, error) { - // NOTE 주의!! - apiKeys := ncloud.APIKey{ - AccessKey: connectionInfo.CredentialInfo.ClientId, - SecretKey: connectionInfo.CredentialInfo.ClientSecret, - } - // Create NCP service client - client := server.NewAPIClient(server.NewConfiguration(&apiKeys)) - return client, nil -} - -func getLbClient(connectionInfo idrv.ConnectionInfo) (*lb.APIClient, error) { - apiKeys := ncloud.APIKey{ - AccessKey: connectionInfo.CredentialInfo.ClientId, - SecretKey: connectionInfo.CredentialInfo.ClientSecret, - } - // Create NCP Classic Load Balancer service client - client := lb.NewAPIClient(lb.NewConfiguration(&apiKeys)) - return client, nil -} - -func (driver *NcpDriver) ConnectCloud(connectionInfo idrv.ConnectionInfo) (icon.CloudConnection, error) { - // 1. get info of credential and region for Test A Cloud from connectionInfo. - // 2. create a client object(or service object) of Test A Cloud with credential info. - // 3. create CloudConnection Instance of "connect/TDA_CloudConnection". - // 4. return CloudConnection Interface of TDA_CloudConnection. - - vmClient, err := getVMClient(connectionInfo) - if err != nil { - return nil, err - } - - lbClient, err := getLbClient(connectionInfo) - if err != nil { - return nil, err - } - - iConn := ncpcon.NcpCloudConnection{ - CredentialInfo: connectionInfo.CredentialInfo, - RegionInfo: connectionInfo.RegionInfo, - VmClient: vmClient, - LbClient: lbClient, - } - - return &iConn, nil -} - -var CloudDriver NcpDriver +var CloudDriver ncp.NcpDriver diff --git a/cloud-control-manager/cloud-driver/drivers/ncpvpc-plugin/NcpVpcDriver-lib.go b/cloud-control-manager/cloud-driver/drivers/ncpvpc-plugin/NcpVpcDriver-lib.go index 7866929d5..007dc022f 100644 --- a/cloud-control-manager/cloud-driver/drivers/ncpvpc-plugin/NcpVpcDriver-lib.go +++ b/cloud-control-manager/cloud-driver/drivers/ncpvpc-plugin/NcpVpcDriver-lib.go @@ -8,129 +8,13 @@ // // by ETRI, 2020.12. // by ETRI, 2022.03. updated +// by ETRI, 2024.07. package main import ( - // "github.com/davecgh/go-spew/spew" - "github.com/sirupsen/logrus" - - cblog "github.com/cloud-barista/cb-log" - idrv "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces" - icon "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces/connect" - - ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go-v2/ncloud" - vserver "github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver" - vpc "github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vpc" - vlb "github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vloadbalancer" - - // ncpvpccon "github.com/cloud-barista/ncpvpc/ncpvpc/connect" // For local testing - ncpvpccon "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/drivers/ncpvpc/connect" + "C" + ncpvpc "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/drivers/ncpvpc" ) -var cblogger *logrus.Logger - -func init() { - // cblog is a global variable. - cblogger = cblog.GetLogger("NCPVPC Handler") -} - -type NcpVpcDriver struct { -} - -func (NcpVpcDriver) GetDriverVersion() string { - return "TEST NCP VPC DRIVER Version 1.0" -} - -func (NcpVpcDriver) GetDriverCapability() idrv.DriverCapabilityInfo { - var drvCapabilityInfo idrv.DriverCapabilityInfo - - // NOTE Temporary Setting - drvCapabilityInfo.ImageHandler = true - drvCapabilityInfo.VPCHandler = true - drvCapabilityInfo.SecurityHandler = true - drvCapabilityInfo.KeyPairHandler = true - drvCapabilityInfo.VNicHandler = false - drvCapabilityInfo.PublicIPHandler = false - drvCapabilityInfo.VMHandler = true - drvCapabilityInfo.VMSpecHandler = true - drvCapabilityInfo.NLBHandler = true - - return drvCapabilityInfo -} - -func getVmClient(connectionInfo idrv.ConnectionInfo) (*vserver.APIClient, error) { - - // NOTE 주의!! - apiKeys := ncloud.APIKey{ - AccessKey: connectionInfo.CredentialInfo.ClientId, - SecretKey: connectionInfo.CredentialInfo.ClientSecret, - } - - // NOTE for just test - // cblogger.Info(apiKeys.AccessKey) - // cblogger.Info(apiKeys.SecretKey) - - // Create NCPVPC service client - client := vserver.NewAPIClient(vserver.NewConfiguration(&apiKeys)) - - return client, nil -} - -func getVpcClient(connectionInfo idrv.ConnectionInfo) (*vpc.APIClient, error) { - apiKeys := ncloud.APIKey{ - AccessKey: connectionInfo.CredentialInfo.ClientId, - SecretKey: connectionInfo.CredentialInfo.ClientSecret, - } - - // Create NCP VPC service client - client := vpc.NewAPIClient(vpc.NewConfiguration(&apiKeys)) - - return client, nil -} - -func getVlbClient(connectionInfo idrv.ConnectionInfo) (*vlb.APIClient, error) { - apiKeys := ncloud.APIKey{ - AccessKey: connectionInfo.CredentialInfo.ClientId, - SecretKey: connectionInfo.CredentialInfo.ClientSecret, - } - - // Create NCP VPC Load Balancer service client - client := vlb.NewAPIClient(vlb.NewConfiguration(&apiKeys)) - - return client, nil -} - -func (driver *NcpVpcDriver) ConnectCloud(connectionInfo idrv.ConnectionInfo) (icon.CloudConnection, error) { - // 1. get info of credential and region for Test A Cloud from connectionInfo. - // 2. create a client object(or service object) of Test A Cloud with credential info. - // 3. create CloudConnection Instance of "connect/TDA_CloudConnection". - // 4. return CloudConnection Interface of TDA_CloudConnection. - - vmClient, err := getVmClient(connectionInfo) - if err != nil { - return nil, err - } - - vpcClient, err := getVpcClient(connectionInfo) - if err != nil { - return nil, err - } - - vlbClient, err := getVlbClient(connectionInfo) - if err != nil { - return nil, err - } - - iConn := ncpvpccon.NcpVpcCloudConnection{ - CredentialInfo: connectionInfo.CredentialInfo, - RegionInfo: connectionInfo.RegionInfo, - VmClient: vmClient, - VpcClient: vpcClient, - VlbClient: vlbClient, - } - - return &iConn, nil -} - -var CloudDriver NcpVpcDriver +var CloudDriver ncpvpc.NcpVpcDriver From d3377951d8e131fbda229bf69b23139129b21fdb Mon Sep 17 00:00:00 2001 From: dev4unet Date: Wed, 17 Jul 2024 07:46:29 +0000 Subject: [PATCH 08/32] Handle Tag values in each handler's constructor --- .../drivers/aws/resources/ClusterHandler.go | 6 ++ .../drivers/aws/resources/CommonAwsFunc.go | 67 ++++++++++++++++- .../drivers/aws/resources/DiskHandler.go | 35 +++++---- .../drivers/aws/resources/KeyPairHandler.go | 13 +++- .../drivers/aws/resources/MyImageHandler.go | 44 ++++++++---- .../drivers/aws/resources/NLBHandler.go | 71 +++++++++++++++++-- .../drivers/aws/resources/SecurityHandler.go | 10 ++- .../drivers/aws/resources/VMHandler.go | 52 +++++++++----- .../drivers/aws/resources/VPCHandler.go | 28 ++++++-- 9 files changed, 263 insertions(+), 63 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go index 21913745e..c3c395584 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go @@ -67,6 +67,11 @@ func (ClusterHandler *AwsClusterHandler) CreateCluster(clusterReqInfo irs.Cluste reqK8sVersion := clusterReqInfo.Version + tagsMap, err := ConvertTagListToTagsMap(clusterReqInfo.TagList, clusterReqInfo.IId.NameId) + if err != nil { + return irs.ClusterInfo{}, fmt.Errorf("failed to convert tags map: %w", err) + } + // create cluster input := &eks.CreateClusterInput{ Name: aws.String(clusterReqInfo.IId.NameId), @@ -77,6 +82,7 @@ func (ClusterHandler *AwsClusterHandler) CreateCluster(clusterReqInfo irs.Cluste //RoleArn: aws.String("arn:aws:iam::012345678910:role/eks-service-role-AWSServiceRoleForAmazonEKS-J7ONKE3BQ4PI"), //RoleArn: aws.String(roleArn), RoleArn: roleArn, + Tags: tagsMap, } //EKS버전 처리(Spider 입력 값 형태 : "1.23.4" / AWS 버전 형태 : "1.23") diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/CommonAwsFunc.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/CommonAwsFunc.go index 683dd7de9..1038689ee 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/CommonAwsFunc.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/CommonAwsFunc.go @@ -386,7 +386,7 @@ func ConvertKeyValueList(v interface{}) ([]irs.KeyValue, error) { //cblogger.Debugf("Key[%s]의 값은 변환 불가 - [%s]", k, errString) //요구에 의해서 Error에서 Warn으로 낮춤 continue } - keyValueList = append(keyValueList, irs.KeyValue{k, value}) + keyValueList = append(keyValueList, irs.KeyValue{Key: k, Value: value}) /* _, ok := v.(string) @@ -504,3 +504,68 @@ func ReplaceEmptyWithNAforLoadBalancerNetwork(obj interface{}) { } } } + +// Function to convert tag list to tag specifications +// nameValue : Automatically adds the "Name" Tag when there is no "Name" Tag in the tagList, and specifies the value you want to use for the "Name" Tag. +func ConvertTagListToTagSpecifications(resourceType string, tagList []irs.KeyValue, nameValue ...string) ([]*ec2.TagSpecification, error) { + // Convert KeyValue list to ec2.Tag list + var ec2Tags []*ec2.Tag + for _, kv := range tagList { + ec2Tags = append(ec2Tags, &ec2.Tag{ + Key: aws.String(kv.Key), + Value: aws.String(kv.Value), + }) + } + + // Add a "Name" tag if nameValue is provided using a variable argument + if len(nameValue) > 0 && nameValue[0] != "" { + nameTagExists := false + for _, tag := range ec2Tags { + if *tag.Key == "Name" { + nameTagExists = true + break + } + } + if !nameTagExists { + ec2Tags = append(ec2Tags, &ec2.Tag{ + Key: aws.String("Name"), + Value: aws.String(nameValue[0]), + }) + } + } + + // If no tags are provided, return an empty slice + if len(ec2Tags) == 0 { + return []*ec2.TagSpecification{}, nil + } + + // Create TagSpecifications + tagSpecifications := []*ec2.TagSpecification{ + { + ResourceType: aws.String(resourceType), + Tags: ec2Tags, + }, + } + + return tagSpecifications, nil +} + +// Function to ConvertTagListToTagsMap +// nameValue : Automatically adds the "Name" Tag when there is no "Name" Tag in the tagList, and specifies the value you want to use for the "Name" Tag. +func ConvertTagListToTagsMap(tagList []irs.KeyValue, nameValue ...string) (map[string]*string, error) { + tagsMap := make(map[string]*string) + + // tagList Convert a list of tags to tagsMap + for _, kv := range tagList { + tagsMap[kv.Key] = aws.String(kv.Value) + } + + // If nameValue is provided using a variable argument, add a "Name" Tag if it doesn't already exist + if len(nameValue) > 0 && nameValue[0] != "" { + if _, exists := tagsMap["Name"]; !exists { + tagsMap["Name"] = aws.String(nameValue[0]) + } + } + + return tagsMap, nil +} diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/DiskHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/DiskHandler.go index 65a5cbde2..36f4057bb 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/DiskHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/DiskHandler.go @@ -4,6 +4,7 @@ package resources import ( "errors" + "fmt" "reflect" "strconv" "strings" @@ -71,25 +72,33 @@ func (DiskHandler *AwsDiskHandler) CreateDisk(diskReqInfo irs.DiskInfo) (irs.Dis volumeSize, _ := strconv.ParseInt(diskReqInfo.DiskSize, 10, 64) volumeType := diskReqInfo.DiskType - // volume 이름을 위해 Tag 지정. - tag := &ec2.Tag{ - Key: aws.String(VOLUME_TAG_DEFAULT), - Value: &diskReqInfo.IId.NameId, - } + /* + // volume 이름을 위해 Tag 지정. + tag := &ec2.Tag{ + Key: aws.String(VOLUME_TAG_DEFAULT), + Value: &diskReqInfo.IId.NameId, + } - var tags []*ec2.Tag - tags = append(tags, tag) - tagSpec := &ec2.TagSpecification{ - ResourceType: aws.String(RESOURCE_TYPE_VOLUME), - Tags: tags, + var tags []*ec2.Tag + tags = append(tags, tag) + tagSpec := &ec2.TagSpecification{ + ResourceType: aws.String(RESOURCE_TYPE_VOLUME), + Tags: tags, + } + var tagSpecs []*ec2.TagSpecification + tagSpecs = append(tagSpecs, tagSpec) + */ + + // Convert TagList to TagSpecifications + tagSpecifications, err := ConvertTagListToTagSpecifications(*aws.String(RESOURCE_TYPE_VOLUME), diskReqInfo.TagList, diskReqInfo.IId.NameId) + if err != nil { + return irs.DiskInfo{}, fmt.Errorf("failed to convert tag list: %w", err) } - var tagSpecs []*ec2.TagSpecification - tagSpecs = append(tagSpecs, tagSpec) input := &ec2.CreateVolumeInput{ AvailabilityZone: aws.String(zone), Size: aws.Int64(volumeSize), - TagSpecifications: tagSpecs, + TagSpecifications: tagSpecifications, } switch diskReqInfo.DiskType { diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/KeyPairHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/KeyPairHandler.go index 551ee0a71..337198191 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/KeyPairHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/KeyPairHandler.go @@ -106,6 +106,12 @@ func (keyPairHandler *AwsKeyPairHandler) CreateKey(keyPairReqInfo irs.KeyPairReq } */ + // Convert TagList to TagSpecifications + tagSpecifications, err := ConvertTagListToTagSpecifications("key-pair", keyPairReqInfo.TagList) + if err != nil { + return irs.KeyPairInfo{}, fmt.Errorf("failed to convert tag list: %w", err) + } + // logger for HisCall callogger := call.GetLogger("HISCALL") callLogInfo := call.CLOUDLOGSCHEMA{ @@ -121,7 +127,8 @@ func (keyPairHandler *AwsKeyPairHandler) CreateKey(keyPairReqInfo irs.KeyPairReq // Creates a new key pair with the given name result, err := keyPairHandler.Client.CreateKeyPair(&ec2.CreateKeyPairInput{ //KeyName: aws.String(keyPairReqInfo.Name), - KeyName: aws.String(keyPairReqInfo.IId.NameId), + KeyName: aws.String(keyPairReqInfo.IId.NameId), + TagSpecifications: tagSpecifications, }) callLogInfo.ElapsedTime = call.Elapsed(callLogStart) @@ -250,7 +257,7 @@ func (keyPairHandler *AwsKeyPairHandler) GetKey(keyIID irs.IID) (irs.KeyPairInfo cblogger.Debug("aerr.Code() : ", aerr.Code()) cblogger.Debug("ok : ", ok) switch aerr.Code() { - default: + default: cblogger.Error(aerr.Error()) return irs.KeyPairInfo{}, aerr } @@ -259,7 +266,7 @@ func (keyPairHandler *AwsKeyPairHandler) GetKey(keyIID irs.IID) (irs.KeyPairInfo cblogger.Error(err.Error()) return irs.KeyPairInfo{}, err } - return irs.KeyPairInfo{}, nil + //return irs.KeyPairInfo{}, nil } callogger.Info(call.String(callLogInfo)) diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/MyImageHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/MyImageHandler.go index 52d15e2d0..8bdca4c6b 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/MyImageHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/MyImageHandler.go @@ -259,26 +259,43 @@ func (ImageHandler *AwsMyImageHandler) SnapshotVM(snapshotReqInfo irs.MyImageInf blockDeviceMappingList = append(blockDeviceMappingList, &blockDeviceMapping) } - var tags []*ec2.Tag - nameTag := &ec2.Tag{ - Key: aws.String(IMAGE_TAG_DEFAULT), - Value: aws.String(snapshotReqInfo.IId.NameId), + /* + var tags []*ec2.Tag + nameTag := &ec2.Tag{ + Key: aws.String(IMAGE_TAG_DEFAULT), + Value: aws.String(snapshotReqInfo.IId.NameId), + } + tags = append(tags, nameTag) + sourceVMTag := &ec2.Tag{ + Key: aws.String(IMAGE_TAG_SOURCE_VM), + Value: aws.String(snapshotReqInfo.SourceVM.SystemId), + } + tags = append(tags, sourceVMTag) + tagSpec := &ec2.TagSpecification{ + ResourceType: aws.String(RESOURCE_TYPE_MYIMAGE), + Tags: tags, + } + var tagSpecs []*ec2.TagSpecification + tagSpecs = append(tagSpecs, tagSpec) + */ + + // Convert TagList to TagSpecifications + tagSpecifications, err := ConvertTagListToTagSpecifications(RESOURCE_TYPE_MYIMAGE, snapshotReqInfo.TagList, snapshotReqInfo.IId.NameId) + if err != nil { + return irs.MyImageInfo{}, fmt.Errorf("failed to convert tag list: %w", err) } - tags = append(tags, nameTag) + + // Add new tags to results sourceVMTag := &ec2.Tag{ Key: aws.String(IMAGE_TAG_SOURCE_VM), Value: aws.String(snapshotReqInfo.SourceVM.SystemId), } - tags = append(tags, sourceVMTag) - tagSpec := &ec2.TagSpecification{ - ResourceType: aws.String(RESOURCE_TYPE_MYIMAGE), - Tags: tags, + + if len(tagSpecifications) > 0 { + tagSpecifications[0].Tags = append(tagSpecifications[0].Tags, sourceVMTag) } - var tagSpecs []*ec2.TagSpecification - tagSpecs = append(tagSpecs, tagSpec) // Image parameter set - input := &ec2.CreateImageInput{ //BlockDeviceMappings: []*ec2.BlockDeviceMapping{ // { @@ -300,7 +317,8 @@ func (ImageHandler *AwsMyImageHandler) SnapshotVM(snapshotReqInfo irs.MyImageInf InstanceId: aws.String(snapshotReqInfo.SourceVM.SystemId), Description: aws.String(snapshotReqInfo.IId.NameId), BlockDeviceMappings: blockDeviceMappingList, - TagSpecifications: tagSpecs, + //TagSpecifications: tagSpecs, + TagSpecifications: tagSpecifications, } cblogger.Debug(input) diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/NLBHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/NLBHandler.go index f934915f9..b4e57b06d 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/NLBHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/NLBHandler.go @@ -44,7 +44,51 @@ type TargetGroupInfo struct { */ } +// Function to convert tag list to ec2 tags array +// nameValue : Automatically adds the "Name" Tag when there is no "Name" Tag in the tagList, and specifies the value you want to use for the "Name" Tag. +func ConvertTagListToTags(tagList []irs.KeyValue, nameValue ...string) ([]*elbv2.Tag, error) { + // Convert KeyValue list to ec2.Tag list + var elbTags []*elbv2.Tag + for _, kv := range tagList { + elbTags = append(elbTags, &elbv2.Tag{ + Key: aws.String(kv.Key), + Value: aws.String(kv.Value), + }) + } + + // Add a "Name" tag if nameValue is provided using a variable argument + if len(nameValue) > 0 && nameValue[0] != "" { + nameTagExists := false + for _, tag := range elbTags { + if *tag.Key == "Name" { + nameTagExists = true + break + } + } + if !nameTagExists { + elbTags = append(elbTags, &elbv2.Tag{ + Key: aws.String("Name"), + Value: aws.String(nameValue[0]), + }) + } + } + + // If no tags are provided, return an empty slice + if len(elbTags) == 0 { + return []*elbv2.Tag{}, nil + } + + return elbTags, nil +} + func (NLBHandler *AwsNLBHandler) CreateListener(nlbReqInfo irs.NLBInfo) (*elbv2.CreateListenerOutput, error) { + + // Convert TagList to ec2 Tags array + tags, err := ConvertTagListToTags(nlbReqInfo.TagList, nlbReqInfo.IId.NameId) + if err != nil { + return nil, fmt.Errorf("failed to convert tag list: %w", err) + } + input := &elbv2.CreateListenerInput{ DefaultActions: []*elbv2.Action{ { @@ -55,6 +99,7 @@ func (NLBHandler *AwsNLBHandler) CreateListener(nlbReqInfo irs.NLBInfo) (*elbv2. LoadBalancerArn: aws.String(nlbReqInfo.IId.SystemId), //생성된 NLB의 ARN 값 //Port: aws.Int64(80), //숫자 값 검증 후 적용 Protocol: aws.String(nlbReqInfo.Listener.Protocol), // AWS NLB : TCP, TLS, UDP, or TCP_UDP + Tags: tags, } //리스너 포트 포메팅 검증 및 셋팅 @@ -129,6 +174,12 @@ func (NLBHandler *AwsNLBHandler) CreateListener(nlbReqInfo irs.NLBInfo) (*elbv2. } func (NLBHandler *AwsNLBHandler) CreateTargetGroup(nlbReqInfo irs.NLBInfo) (*elbv2.CreateTargetGroupOutput, error) { + // Convert TagList to ec2 Tags array + tags, err := ConvertTagListToTags(nlbReqInfo.TagList, nlbReqInfo.IId.NameId) + if err != nil { + return nil, fmt.Errorf("failed to convert tag list: %w", err) + } + input := &elbv2.CreateTargetGroupInput{ Name: aws.String(nlbReqInfo.IId.NameId), TargetType: aws.String("instance"), // instance , ip, lambda @@ -142,6 +193,7 @@ func (NLBHandler *AwsNLBHandler) CreateTargetGroup(nlbReqInfo irs.NLBInfo) (*elb HealthCheckPort: aws.String(nlbReqInfo.HealthChecker.Port), //HealthCheckIntervalSeconds: aws.Int64(int64(nlbReqInfo.HealthChecker.Interval)), // 5초이상 // 0 이상의 값이 있을 때만 설정하도록 변경 //HealthCheckTimeoutSeconds: aws.Int64(int64(nlbReqInfo.HealthChecker.Timeout)), // 0 이상의 값이 있을 때만 설정하도록 변경 + Tags: tags, } //AWS TargetGroup 포트 포메팅 검증 및 셋팅 @@ -314,7 +366,7 @@ func (NLBHandler *AwsNLBHandler) ExtractVmSubnets(VMs *[]irs.IID) ([]*string, er //최종 사용할 서브넷 목록만 추출함. subnetList := []*string{} for key, val := range mapZone { - cblogger.Debug("AZ[%s] Subnet[%s]", key, val) + cblogger.Debugf("AZ[%s] Subnet[%s]", key, val) subnetList = append(subnetList, aws.String(val)) } @@ -427,6 +479,12 @@ func (NLBHandler *AwsNLBHandler) CreateNLB(nlbReqInfo irs.NLBInfo) (irs.NLBInfo, return irs.NLBInfo{}, errVmInfo } + // Convert TagList to ec2 Tags array + tags, err := ConvertTagListToTags(nlbReqInfo.TagList, nlbReqInfo.IId.NameId) + if err != nil { + return irs.NLBInfo{}, fmt.Errorf("failed to convert tag list: %w", err) + } + input := &elbv2.CreateLoadBalancerInput{ Name: aws.String(nlbReqInfo.IId.NameId), Type: aws.String("network"), //NLB 생성 @@ -443,6 +501,7 @@ func (NLBHandler *AwsNLBHandler) CreateNLB(nlbReqInfo irs.NLBInfo) (irs.NLBInfo, //aws.String("subnet-0cf7417f83fd0fd47"), //New-CB-Subnet-NLB-1d1 }, */ + Tags: tags, } if nlbReqInfo.Listener.IP == "" { @@ -874,7 +933,7 @@ func (NLBHandler *AwsNLBHandler) ExtractVMGroupInfo(nlbIID irs.IID) (TargetGroup // 헬스 상태별 VM 목록 처리 //========================= targetHealthInfo, errHealthInfo := NLBHandler.ExtractVMGroupHealthInfo(*result.TargetGroups[0].TargetGroupArn) - if err != nil { + if errHealthInfo != nil { return TargetGroupInfo{}, errHealthInfo } targetGroupInfo.VMGroup.VMs = targetHealthInfo.AllVMs @@ -1001,7 +1060,7 @@ func (NLBHandler *AwsNLBHandler) DeleteListener(listenerArn *string) (bool, erro result, err := NLBHandler.Client.DeleteListener(input) if err != nil { - cblogger.Errorf("Listener[%s] deleted failed", listenerArn) + cblogger.Errorf("Listener[%s] deleted failed", *listenerArn) if aerr, ok := err.(awserr.Error); ok { switch aerr.Code() { case elbv2.ErrCodeListenerNotFoundException: @@ -1019,7 +1078,7 @@ func (NLBHandler *AwsNLBHandler) DeleteListener(listenerArn *string) (bool, erro return false, err } - cblogger.Infof("Listener[%s] deleted complate", listenerArn) + cblogger.Infof("Listener[%s] deleted complate", *listenerArn) cblogger.Debug(result) return true, nil @@ -1032,7 +1091,7 @@ func (NLBHandler *AwsNLBHandler) DeleteTargetGroup(targetGroupArn *string) (bool result, err := NLBHandler.Client.DeleteTargetGroup(input) if err != nil { - cblogger.Errorf("TargetGroup[%s] deleted failed", targetGroupArn) + cblogger.Errorf("TargetGroup[%s] deleted failed", *targetGroupArn) if aerr, ok := err.(awserr.Error); ok { switch aerr.Code() { case elbv2.ErrCodeResourceInUseException: @@ -1048,7 +1107,7 @@ func (NLBHandler *AwsNLBHandler) DeleteTargetGroup(targetGroupArn *string) (bool return false, err } - cblogger.Infof("TargetGroup[%s] deleted complate", targetGroupArn) + cblogger.Infof("TargetGroup[%s] deleted complate", *targetGroupArn) cblogger.Debug(result) return true, nil diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/SecurityHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/SecurityHandler.go index 7b04a7bad..10aba285a 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/SecurityHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/SecurityHandler.go @@ -12,6 +12,7 @@ package resources import ( "errors" + "fmt" "reflect" "strconv" @@ -52,6 +53,12 @@ func (securityHandler *AwsSecurityHandler) CreateSecurity(securityReqInfo irs.Se */ vpcId := securityReqInfo.VpcIID.SystemId + // Convert TagList to TagSpecifications + tagSpecifications, err := ConvertTagListToTagSpecifications("security-group", securityReqInfo.TagList, securityReqInfo.IId.NameId) + if err != nil { + return irs.SecurityInfo{}, fmt.Errorf("failed to convert tag list: %w", err) + } + // Create the security group with the VPC, name and description. //createRes, err := securityHandler.Client.CreateSecurityGroup(&ec2.CreateSecurityGroupInput{ input := ec2.CreateSecurityGroupInput{ @@ -60,7 +67,8 @@ func (securityHandler *AwsSecurityHandler) CreateSecurity(securityReqInfo irs.Se //Description: aws.String(securityReqInfo.Name), Description: aws.String(securityReqInfo.IId.NameId), // VpcId: aws.String(securityReqInfo.VpcId),awsCBNetworkInfo - VpcId: aws.String(vpcId), + VpcId: aws.String(vpcId), + TagSpecifications: tagSpecifications, } cblogger.Debugf("Security group creation request information", input) // logger for HisCall diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/VMHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/VMHandler.go index f250f5682..6bc0bfe0b 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/VMHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/VMHandler.go @@ -9,6 +9,7 @@ package resources import ( "encoding/base64" "errors" + "fmt" "io/ioutil" "os" "reflect" @@ -210,7 +211,7 @@ func (vmHandler *AwsVMHandler) StartVM(vmReqInfo irs.VMReqInfo) (irs.VMInfo, err minCount := aws.Int64(1) maxCount := aws.Int64(1) keyName := vmReqInfo.KeyPairIID.SystemId - baseName := vmReqInfo.IId.NameId + //baseName := vmReqInfo.IId.NameId subnetID := vmReqInfo.SubnetIID.SystemId /* 2021-10-26 이슈 #480에 의해 제거 @@ -329,6 +330,15 @@ func (vmHandler *AwsVMHandler) StartVM(vmReqInfo irs.VMReqInfo) (irs.VMInfo, err } */ + //============================= + // Tag + //============================= + // Convert TagList to TagSpecifications + tagSpecifications, err := ConvertTagListToTagSpecifications("instance", vmReqInfo.TagList, vmReqInfo.IId.NameId) + if err != nil { + return irs.VMInfo{}, fmt.Errorf("failed to convert tag list: %w", err) + } + //============================= // VM생성 처리 //============================= @@ -363,7 +373,8 @@ func (vmHandler *AwsVMHandler) StartVM(vmReqInfo irs.VMReqInfo) (irs.VMInfo, err }, //ec2.InstanceNetworkInterfaceSpecification - UserData: userDataBase64, + UserData: userDataBase64, + TagSpecifications: tagSpecifications, } //============================= @@ -466,25 +477,28 @@ func (vmHandler *AwsVMHandler) StartVM(vmReqInfo irs.VMReqInfo) (irs.VMInfo, err newVmId := *runResult.Instances[0].InstanceId cblogger.Infof("[%s] VM has been created.", newVmId) - if baseName != "" { - // Tag에 VM Name 설정 - _, errtag := vmHandler.Client.CreateTags(&ec2.CreateTagsInput{ - Resources: []*string{runResult.Instances[0].InstanceId}, - Tags: []*ec2.Tag{ - { - Key: aws.String("Name"), - Value: aws.String(baseName), + /* + if baseName != "" { + // Tag에 VM Name 설정 + _, errtag := vmHandler.Client.CreateTags(&ec2.CreateTagsInput{ + Resources: []*string{runResult.Instances[0].InstanceId}, + Tags: []*ec2.Tag{ + { + Key: aws.String("Name"), + Value: aws.String(baseName), + }, }, - }, - }) - if errtag != nil { - cblogger.Errorf("Failed to set Name Tag for [%s] VM", newVmId) - cblogger.Error(errtag) - //return irs.VMInfo{}, errtag + }) + if errtag != nil { + cblogger.Errorf("Failed to set Name Tag for [%s] VM", newVmId) + cblogger.Error(errtag) + //return irs.VMInfo{}, errtag + } + } else { + cblogger.Error("Name Tag will not be set because vmReqInfo.IId.NameId is not provided.") } - } else { - cblogger.Error("Name Tag will not be set because vmReqInfo.IId.NameId is not provided.") - } + */ + //Public IP및 최신 정보 전달을 위해 부팅이 완료될 때까지 대기했다가 전달하는 것으로 변경 함. //cblogger.Info("Public IP 할당 및 VM의 최신 정보 획득을 위해 EC2가 Running 상태가 될때까지 대기") diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/VPCHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/VPCHandler.go index d302b0807..ce148c44e 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/VPCHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/VPCHandler.go @@ -12,6 +12,7 @@ package resources import ( "errors" + "fmt" "reflect" "strconv" @@ -38,8 +39,16 @@ func (VPCHandler *AwsVPCHandler) CreateVPC(vpcReqInfo irs.VPCReqInfo) (irs.VPCIn return irs.VPCInfo{}, errors.New("Connection information does not contain Zone information.") } + // Convert TagList to TagSpecifications + tagSpecifications, err := ConvertTagListToTagSpecifications("vpc", vpcReqInfo.TagList, vpcReqInfo.IId.NameId) + if err != nil { + return irs.VPCInfo{}, fmt.Errorf("failed to convert tag list: %w", err) + } + + // Create VPC input with tag specifications input := &ec2.CreateVpcInput{ - CidrBlock: aws.String(vpcReqInfo.IPv4_CIDR), + CidrBlock: aws.String(vpcReqInfo.IPv4_CIDR), + TagSpecifications: tagSpecifications, } //cblogger.Debug(input) @@ -81,12 +90,17 @@ func (VPCHandler *AwsVPCHandler) CreateVPC(vpcReqInfo irs.VPCReqInfo) (irs.VPCIn retVpcInfo := ExtractVpcDescribeInfo(result.Vpc) retVpcInfo.IId.NameId = vpcReqInfo.IId.NameId // NameId는 요청 받은 값으로 리턴해야 함. - //IGW Name Tag 설정 - if SetNameTag(VPCHandler.Client, *result.Vpc.VpcId, vpcReqInfo.IId.NameId) { - cblogger.Infof("set name %s to VPC", vpcReqInfo.IId.NameId) - } else { - cblogger.Errorf("set name %s to VPC failed", vpcReqInfo.IId.NameId) - } + /* + // 2024.07.16 Delete with Tag support + if len(tagSpecifications) == 0 { + //IGW Name Tag 설정 + if SetNameTag(VPCHandler.Client, *result.Vpc.VpcId, vpcReqInfo.IId.NameId) { + cblogger.Infof("set name %s to VPC", vpcReqInfo.IId.NameId) + } else { + cblogger.Errorf("set name %s to VPC failed", vpcReqInfo.IId.NameId) + } + } + */ //==================================== // PublicIP 할당을 위해 IGW 생성및 연결 From bde405a044e379c7bb73fb100a45cfbedd12b0a4 Mon Sep 17 00:00:00 2001 From: dev4unet Date: Wed, 17 Jul 2024 07:59:53 +0000 Subject: [PATCH 09/32] Fixed some Go syntax warnings --- .../cloud-driver/drivers/aws/resources/ClusterHandler.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go index c3c395584..f07a1b43a 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go @@ -91,12 +91,9 @@ func (ClusterHandler *AwsClusterHandler) CreateCluster(clusterReqInfo irs.Cluste switch len(arrVer) { case 2: // 그대로 적용 input.Version = aws.String(reqK8sVersion) - break case 3: // 앞의 2자리만 취함. (정상적인 입력 형태) input.Version = aws.String(arrVer[0] + "." + arrVer[1]) - break default: // 위 2가지 외에는 CSP의 기본값(최신버전)을 적용 함. - break } } @@ -977,6 +974,7 @@ func (NodeGroupHandler *AwsClusterHandler) convertNodeGroup(nodeGroupOutput *eks nodeGroupInfo.MaxNodeSize = int(*scalingConfig.MaxSize) if nodeGroupTagList == nil { + nodeGroupTagList = make(map[string]*string) // nil 체크 후 초기화 nodeGroupTagList[NODEGROUP_TAG] = nodeGroupName // 값이없으면 nodeGroupName이랑 같은값으로 set. } nodeGroupTag := "" From 32e7a24589265eb2524d0985d64fbfe05276ac24 Mon Sep 17 00:00:00 2001 From: dev4unet Date: Wed, 17 Jul 2024 09:13:43 +0000 Subject: [PATCH 10/32] Add hiscall to FindTag --- .../drivers/aws/resources/TagHandler.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go index a5abf02bc..64aab4508 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go @@ -336,10 +336,15 @@ func (tagHandler *AwsTagHandler) FindTag(resType irs.RSType, keyword string) ([] cblogger.Debug(keyInput) } + hiscallInfo := GetCallLogScheme(tagHandler.Region, call.TAG, keyword, "FindTag(key):DescribeTags()") + start := call.Start() + keyResult, err := tagHandler.Client.DescribeTags(keyInput) if err != nil { + LoggingError(hiscallInfo, err) return nil, fmt.Errorf("failed to describe tags by key: %w", err) } + LoggingInfo(hiscallInfo, start) processTags(keyResult) valueInput := &ec2.DescribeTagsInput{ @@ -355,10 +360,15 @@ func (tagHandler *AwsTagHandler) FindTag(resType irs.RSType, keyword string) ([] cblogger.Debug(valueInput) } + hiscallInfo2 := GetCallLogScheme(tagHandler.Region, call.TAG, keyword, "FindTag(value):DescribeTags()") + start2 := call.Start() + valueResult, err := tagHandler.Client.DescribeTags(valueInput) if err != nil { + LoggingError(hiscallInfo2, err) return nil, fmt.Errorf("failed to describe tags by value: %w", err) } + LoggingInfo(hiscallInfo2, start2) processTags(valueResult) } else { // Search all tags if keyword is empty or "*" @@ -366,10 +376,15 @@ func (tagHandler *AwsTagHandler) FindTag(resType irs.RSType, keyword string) ([] Filters: filters, } + hiscallInfo := GetCallLogScheme(tagHandler.Region, call.TAG, keyword, "FindTag(all):DescribeTags()") + start := call.Start() + result, err := tagHandler.Client.DescribeTags(input) if err != nil { + LoggingError(hiscallInfo, err) return nil, fmt.Errorf("failed to describe tags: %w", err) } + LoggingInfo(hiscallInfo, start) processTags(result) } From 097e2c6cfa63df25afd26d88d5eebfb49aee1d40 Mon Sep 17 00:00:00 2001 From: dev4unet Date: Thu, 18 Jul 2024 02:27:32 +0000 Subject: [PATCH 11/32] Fix some message warnings --- .../drivers/aws/resources/CommonHandler.go | 157 +++++++++++++++++- 1 file changed, 149 insertions(+), 8 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/CommonHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/CommonHandler.go index a39a85ab7..15bd583cf 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/CommonHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/CommonHandler.go @@ -2,6 +2,7 @@ package resources import ( "errors" + "fmt" "reflect" "strings" @@ -9,6 +10,7 @@ import ( "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ec2" call "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/call-log" + idrv "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces" irs "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces/resources" ) @@ -57,7 +59,7 @@ func DescribeInstanceById(svc *ec2.EC2, vmIID irs.IID) (*ec2.Instance, error) { var iid irs.IID if vmIID == iid { - return nil, errors.New("instanceID is empty.") + return nil, errors.New("instanceID is empty") } vmIIDs = append(vmIIDs, vmIID) @@ -69,7 +71,7 @@ func DescribeInstanceById(svc *ec2.EC2, vmIID irs.IID) (*ec2.Instance, error) { if len(result.Reservations) < 1 || len(result.Reservations[0].Instances) < 1 { - return nil, errors.New(vmIID.SystemId + " instance not found.") + return nil, errors.New(vmIID.SystemId + " instance not found") } instance := result.Reservations[0].Instances[0] @@ -492,7 +494,7 @@ func DescribeImageById(svc *ec2.EC2, imageIID *irs.IID, owners []*string) (*ec2. var iid irs.IID if *imageIID == iid { - return nil, errors.New("imageID is empty.") + return nil, errors.New("imageID is empty") } imageIIDs = append(imageIIDs, imageIID) @@ -526,11 +528,11 @@ func GetImageSizeFromEc2Image(ec2Image *ec2.Image) (int64, error) { return *isize, nil } else { cblogger.Error("Ebs information not found in BlockDeviceMappings.") - return -1, errors.New("Ebs information not found in BlockDeviceMappings.") + return -1, errors.New("Ebs information not found in BlockDeviceMappings") } } else { cblogger.Error("BlockDeviceMappings information not found.") - return -1, errors.New("BlockDeviceMappings information not found.") + return -1, errors.New("BlockDeviceMappings information not found") } } @@ -569,7 +571,7 @@ func GetSnapshotIdFromEc2Image(ec2Image *ec2.Image) ([]string, error) { } } else { cblogger.Error("BlockDeviceMappings information not found.") - return snapshotIds, errors.New("BlockDeviceMappings information not found.") + return snapshotIds, errors.New("BlockDeviceMappings information not found") } return snapshotIds, nil @@ -584,11 +586,11 @@ func GetDisksFromEc2Image(ec2Image *ec2.Image) ([]irs.IID, error) { return diskIIDs, nil } else { cblogger.Error("Ebs information not found in BlockDeviceMappings.") - return diskIIDs, errors.New("Ebs information not found in BlockDeviceMappings.") + return diskIIDs, errors.New("Ebs information not found in BlockDeviceMappings") } } else { cblogger.Error("BlockDeviceMappings information not found.") - return diskIIDs, errors.New("BlockDeviceMappings information not found.") + return diskIIDs, errors.New("BlockDeviceMappings information not found") } } @@ -765,3 +767,142 @@ func DescribeAvailabilityZones(client *ec2.EC2, AllRegionsBool bool) (*ec2.Descr } // ---------------- RegionZone area end ----------// + +// ---------------- Tag area start ----------// +// Find tags by tag key or value +// resType: ALL | VPC, SUBNET, etc.,. +// keyword: The keyword to search for in the tag key or value. +// if you want to find all tags, set keyword to "" or "*". +func FindTagOrValue(client *ec2.EC2, regionInfo idrv.RegionInfo, resType irs.RSType, keyword string) ([]*irs.TagInfo, error) { + cblogger.Debugf("resType : [%s] / keyword : [%s]", resType, keyword) + + var filters []*ec2.Filter + + // Add resource type filter if resType is not ALL + if resType != irs.ALL { + if awsResType, ok := rsTypeToAwsResourceTypeMap[resType]; ok { + filters = append(filters, &ec2.Filter{ + Name: aws.String("resource-type"), + Values: []*string{ + aws.String(awsResType), + }, + }) + } else { + return nil, fmt.Errorf("unsupported resource type: %s", resType) + } + } + + tagInfoMap := make(map[string]*irs.TagInfo) + + // Function to process tags and add them to tagInfoMap + processTags := func(result *ec2.DescribeTagsOutput) { + if cblogger.Level.String() == "debug" { + cblogger.Debug(result) + //cblogger.Debug("=================================") + //spew.Dump(result) + //cblogger.Debug("=================================") + } + + for _, tag := range result.Tags { + resID := aws.StringValue(tag.ResourceId) + + awsResType := aws.StringValue(tag.ResourceType) + rType, exists := awsResourceTypeToRSTypeMap[awsResType] + if !exists { + //@TODO - 변환 실패한 리소스의 경우 UNKNOWN을 만들거나 에러 로그만 찍거나 결정 필요할 듯 + cblogger.Errorf("No RSType matching [%s] found.", awsResType) + + rType = irs.RSType(awsResType) // Use the raw AWS resource type if not mapped + } + + if _, exists := tagInfoMap[resID]; !exists { + tagInfoMap[resID] = &irs.TagInfo{ + ResType: rType, + ResIId: irs.IID{ + SystemId: resID, + }, + } + } + tagInfoMap[resID].TagList = append(tagInfoMap[resID].TagList, irs.KeyValue{ + Key: aws.StringValue(tag.Key), + Value: aws.StringValue(tag.Value), + }) + } + } + + // Search by tag-key if keyword is not empty or "*" + if keyword != "" && keyword != "*" { + keyInput := &ec2.DescribeTagsInput{ + Filters: append(filters, &ec2.Filter{ + Name: aws.String("tag-key"), + Values: []*string{ + aws.String(keyword), + }, + }), + } + + if cblogger.Level.String() == "debug" { + cblogger.Debug(keyInput) + } + + hiscallInfo := GetCallLogScheme(regionInfo, call.TAG, keyword, "FindTag(key):DescribeTags()") + start := call.Start() + + keyResult, err := client.DescribeTags(keyInput) + if err != nil { + LoggingError(hiscallInfo, err) + return nil, fmt.Errorf("failed to describe tags by key: %w", err) + } + LoggingInfo(hiscallInfo, start) + processTags(keyResult) + + valueInput := &ec2.DescribeTagsInput{ + Filters: append(filters, &ec2.Filter{ + Name: aws.String("tag-value"), + Values: []*string{ + aws.String(keyword), + }, + }), + } + + if cblogger.Level.String() == "debug" { + cblogger.Debug(valueInput) + } + + hiscallInfo2 := GetCallLogScheme(regionInfo, call.TAG, keyword, "FindTag(value):DescribeTags()") + start2 := call.Start() + + valueResult, err := client.DescribeTags(valueInput) + if err != nil { + LoggingError(hiscallInfo2, err) + return nil, fmt.Errorf("failed to describe tags by value: %w", err) + } + LoggingInfo(hiscallInfo2, start2) + processTags(valueResult) + } else { + // Search all tags if keyword is empty or "*" + input := &ec2.DescribeTagsInput{ + Filters: filters, + } + + hiscallInfo := GetCallLogScheme(regionInfo, call.TAG, keyword, "FindTag(all):DescribeTags()") + start := call.Start() + + result, err := client.DescribeTags(input) + if err != nil { + LoggingError(hiscallInfo, err) + return nil, fmt.Errorf("failed to describe tags: %w", err) + } + LoggingInfo(hiscallInfo, start) + processTags(result) + } + + var tagInfos []*irs.TagInfo + for _, tagInfo := range tagInfoMap { + tagInfos = append(tagInfos, tagInfo) + } + + return tagInfos, nil +} + +// ---------------- Tag area end ----------// From 6d531ef2ae6bd2dd6b11528ed87dd627eed9421b Mon Sep 17 00:00:00 2001 From: innodreamer Date: Thu, 18 Jul 2024 18:06:51 +0900 Subject: [PATCH 12/32] Apply NCP's Updated Parameter Return Values about VMImage/MyImage --- .../drivers/ncp/resources/ImageHandler.go | 32 +++++++++++++++---- .../drivers/ncp/resources/MyImageHandler.go | 17 ++++++---- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/ncp/resources/ImageHandler.go b/cloud-control-manager/cloud-driver/drivers/ncp/resources/ImageHandler.go index bffd56e40..f533af4b5 100644 --- a/cloud-control-manager/cloud-driver/drivers/ncp/resources/ImageHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ncp/resources/ImageHandler.go @@ -12,6 +12,7 @@ import ( "fmt" "strconv" "strings" + // "github.com/davecgh/go-spew/spew" ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go-v2/ncloud" server "github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/server" @@ -117,7 +118,7 @@ func MappingImageInfo(serverImage server.Product) irs.ImageInfo { NameId: *serverImage.ProductCode, SystemId: *serverImage.ProductCode, }, - GuestOS: *serverImage.ProductDescription, + GuestOS: *serverImage.OsInformation, Status: "available", } @@ -126,9 +127,9 @@ func MappingImageInfo(serverImage server.Product) irs.ImageInfo { {Key: "PlatformType", Value: *serverImage.PlatformType.CodeName}, {Key: "InfraResourceType", Value: *serverImage.InfraResourceType.CodeName}, {Key: "BaseBlockStorageSize(GB)", Value: strconv.FormatFloat(float64(*serverImage.BaseBlockStorageSize)/(1024*1024*1024), 'f', 0, 64)}, - //{Key: "OsInformation", Value: *serverImage.OsInformation}, - //{Key: "DB Type", Value: *serverImage.DbKindCode}, - //{Key: "NCP GenerationCode", Value: *serverImage.GenerationCode}, + // {Key: "OsInformation", Value: *serverImage.OsInformation}, + // {Key: "DB Type", Value: *serverImage.DbKindCode}, + // {Key: "NCP GenerationCode", Value: *serverImage.GenerationCode}, } keyValueList = append(keyValueList, irs.KeyValue{Key: "Description", Value: *serverImage.ProductDescription}) imageInfo.KeyValueList = keyValueList @@ -192,11 +193,30 @@ func (imageHandler *NcpImageHandler) GetNcpImageInfo(imageIID irs.IID) (*server. return nil, createErr } - imageReq := server.GetServerImageProductListRequest{ProductCode: ncloud.String(imageIID.SystemId)} + // cblogger.Info("\n\n### imageIID : ") + // spew.Dump(imageIID) + // cblogger.Info("\n") + + vmHandler := NcpVMHandler{ + RegionInfo: imageHandler.RegionInfo, + VMClient: imageHandler.VMClient, + } + regionNo, err := vmHandler.GetRegionNo(imageHandler.RegionInfo.Region) + if err != nil { + newErr := fmt.Errorf("Failed to Get NCP Region No of the Region Code : [%v]", err) + cblogger.Error(newErr.Error()) + LoggingError(callLogInfo, newErr) + return nil, newErr + } + + imageReq := server.GetServerImageProductListRequest{ + ProductCode: ncloud.String(imageIID.SystemId), + RegionNo: regionNo, + } callLogStart := call.Start() result, err := imageHandler.VMClient.V2Api.GetServerImageProductList(&imageReq) if err != nil { - newErr := fmt.Errorf("Failed to Find Image list from NCP : [%v]", err) + newErr := fmt.Errorf("Failed to Get Image list from NCP : [%v]", err) cblogger.Error(newErr.Error()) LoggingError(callLogInfo, newErr) return nil, newErr diff --git a/cloud-control-manager/cloud-driver/drivers/ncp/resources/MyImageHandler.go b/cloud-control-manager/cloud-driver/drivers/ncp/resources/MyImageHandler.go index 80537b76a..c1f969f34 100644 --- a/cloud-control-manager/cloud-driver/drivers/ncp/resources/MyImageHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ncp/resources/MyImageHandler.go @@ -338,6 +338,7 @@ func (myImageHandler *NcpMyImageHandler) MappingMyImageInfo(myImage *server.Memb {Key: "Region", Value: myImageHandler.RegionInfo.Region}, {Key: "OriginalImageProductCode", Value: *myImage.OriginalServerImageProductCode}, {Key: "MyImagePlatformType", Value: *myImage.MemberServerImagePlatformType.CodeName}, + {Key: "OriginalOsInformation", Value: *myImage.OriginalOsInformation}, {Key: "CreateDate", Value: *myImage.CreateDate}, } myImageInfo.KeyValueList = keyValueList @@ -383,8 +384,8 @@ func (myImageHandler *NcpMyImageHandler) GetNcpMemberServerImageInfo(myImageIID LoggingInfo(callLogInfo, callLogStart) if len(result.MemberServerImageList) < 1 { - newErr := fmt.Errorf("Failed to Get the Member Server Image List from NCP. Member Server Image does Not Exist!!") - cblogger.Error(newErr.Error()) + newErr := fmt.Errorf("The Member Server Image does Not Exist!!") + cblogger.Debug(newErr.Error()) LoggingError(callLogInfo, newErr) return server.MemberServerImage{}, newErr } else { @@ -424,7 +425,9 @@ func (myImageHandler *NcpMyImageHandler) GetOriginImageOSPlatform(imageIID irs.I LoggingError(callLogInfo, newErr) return "", newErr } else { - imagePlatformType := strings.ToUpper(*ncpImageInfo.PlatformType.CodeName) + // cblogger.Infof("### ImageOsInformation : [%s]", *ncpImageInfo.OsInformation) + imagePlatformType := strings.ToUpper(*ncpImageInfo.OsInformation) + var originImagePlatform string if strings.Contains(imagePlatformType, "UBUNTU") { originImagePlatform = "UBUNTU" @@ -444,13 +447,13 @@ func (myImageHandler *NcpMyImageHandler) GetOriginImageOSPlatform(imageIID irs.I memberServerImageInfo, err := myImageHandler.GetNcpMemberServerImageInfo(imageIID) if err != nil { newErr := fmt.Errorf("Failed to Get NCP Member Server Image Info. [%v]", err.Error()) - cblogger.Error(newErr.Error()) + cblogger.Debug(newErr.Error()) LoggingError(callLogInfo, newErr) return "", newErr } - cblogger.Infof("### MyImagePlatformType : [%s]", *memberServerImageInfo.MemberServerImagePlatformType.CodeName) - - imagePlatformType := strings.ToUpper(*memberServerImageInfo.MemberServerImagePlatformType.CodeName) + // cblogger.Infof("### MyImageOriginalOsInformation : [%s]", *memberServerImageInfo.OriginalOsInformation) + imagePlatformType := strings.ToUpper(*memberServerImageInfo.OriginalOsInformation) + var originImagePlatform string if strings.Contains(imagePlatformType, "UBUNTU") { originImagePlatform = "UBUNTU" From 72add2ba124c2e0972f25d1c5438786daa499790 Mon Sep 17 00:00:00 2001 From: innodreamer Date: Thu, 18 Jul 2024 18:10:58 +0900 Subject: [PATCH 13/32] Change NCP Classic Default VMImage and VMSpec for Test --- api-runtime/rest-runtime/admin-web/AdminWeb-VM.go | 4 ++-- test/vm-cb-user-validation-cli/common/ncp/setup.env | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api-runtime/rest-runtime/admin-web/AdminWeb-VM.go b/api-runtime/rest-runtime/admin-web/AdminWeb-VM.go index 6bf214319..90f4e50bd 100644 --- a/api-runtime/rest-runtime/admin-web/AdminWeb-VM.go +++ b/api-runtime/rest-runtime/admin-web/AdminWeb-VM.go @@ -590,8 +590,8 @@ func VM(c echo.Context) error { imageName = "16681742-f408-444d-a430-dd21a4bef42c" specName = "ETRI-small-2" case "NCP": - imageName = "SPSW0LINUX000052" - specName = "SPSVRHICPUSSD002" + imageName = "SPSW0LINUX000139" + specName = "SPSVRSTAND000005" case "NCPVPC": imageName = "SW.VSVR.OS.LNX64.UBNTU.SVR2004.B050" specName = "SVR.VSVR.HICPU.C004.M008.NET.SSD.B050.G002" diff --git a/test/vm-cb-user-validation-cli/common/ncp/setup.env b/test/vm-cb-user-validation-cli/common/ncp/setup.env index 5e7fbebf2..b83ba8959 100644 --- a/test/vm-cb-user-validation-cli/common/ncp/setup.env +++ b/test/vm-cb-user-validation-cli/common/ncp/setup.env @@ -1,5 +1,5 @@ CONN_CONFIG=ncp-korea1-config -IMAGE_NAME=SPSW0LINUX000130 -SPEC_NAME=SPSVRHICPUSSD002 +IMAGE_NAME=SPSW0LINUX000139 +SPEC_NAME=SPSVRSTAND000005 SG_NAME=spider-sg01 From 9ed5ed77d61e5b9590e5be3a69a100daf7306a82 Mon Sep 17 00:00:00 2001 From: dev4unet Date: Thu, 18 Jul 2024 09:45:10 +0000 Subject: [PATCH 14/32] Added TagHandler implementation to each handler and common function GetResourceTag() --- .../drivers/aws/connect/AwsCloudConnection.go | 41 +++-- .../drivers/aws/main/Test_Resources.go | 6 +- .../drivers/aws/resources/ClusterHandler.go | 1 + .../drivers/aws/resources/CommonHandler.go | 151 ++---------------- .../drivers/aws/resources/DiskHandler.go | 5 +- .../drivers/aws/resources/KeyPairHandler.go | 1 + .../drivers/aws/resources/MyImageHandler.go | 5 +- .../drivers/aws/resources/NLBHandler.go | 5 +- .../drivers/aws/resources/SecurityHandler.go | 5 +- .../drivers/aws/resources/VMHandler.go | 7 +- .../drivers/aws/resources/VPCHandler.go | 8 +- 11 files changed, 72 insertions(+), 163 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/aws/connect/AwsCloudConnection.go b/cloud-control-manager/cloud-driver/drivers/aws/connect/AwsCloudConnection.go index bf39d9e64..4530a7323 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/connect/AwsCloudConnection.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/connect/AwsCloudConnection.go @@ -80,41 +80,50 @@ func (cloudConn *AwsCloudConnection) Close() error { } func (cloudConn *AwsCloudConnection) CreateKeyPairHandler() (irs.KeyPairHandler, error) { - keyPairHandler := ars.AwsKeyPairHandler{cloudConn.CredentialInfo, cloudConn.Region, cloudConn.KeyPairClient} + tagHandler := cloudConn.CreateAwsTagHandler() + keyPairHandler := ars.AwsKeyPairHandler{CredentialInfo: cloudConn.CredentialInfo, Region: cloudConn.Region, Client: cloudConn.KeyPairClient, TagHandler: &tagHandler} //keyPairHandler := ars.AwsKeyPairHandler{cloudConn.Region, cloudConn.KeyPairClient} return &keyPairHandler, nil } func (cloudConn *AwsCloudConnection) CreateVMHandler() (irs.VMHandler, error) { - vmHandler := ars.AwsVMHandler{cloudConn.Region, cloudConn.VMClient} + tagHandler := cloudConn.CreateAwsTagHandler() + vmHandler := ars.AwsVMHandler{Region: cloudConn.Region, Client: cloudConn.VMClient, TagHandler: &tagHandler} return &vmHandler, nil } func (cloudConn *AwsCloudConnection) CreateVPCHandler() (irs.VPCHandler, error) { - handler := ars.AwsVPCHandler{cloudConn.Region, cloudConn.VNetworkClient} + tagHandler := cloudConn.CreateAwsTagHandler() + handler := ars.AwsVPCHandler{Region: cloudConn.Region, Client: cloudConn.VNetworkClient, TagHandler: &tagHandler} return &handler, nil } // func (cloudConn *AwsCloudConnection) CreateImageHandler() (irs2.ImageHandler, error) { func (cloudConn *AwsCloudConnection) CreateImageHandler() (irs.ImageHandler, error) { - handler := ars.AwsImageHandler{cloudConn.Region, cloudConn.ImageClient} + handler := ars.AwsImageHandler{Region: cloudConn.Region, Client: cloudConn.ImageClient} return &handler, nil } func (cloudConn *AwsCloudConnection) CreateSecurityHandler() (irs.SecurityHandler, error) { - handler := ars.AwsSecurityHandler{cloudConn.Region, cloudConn.SecurityClient} + tagHandler := cloudConn.CreateAwsTagHandler() + handler := ars.AwsSecurityHandler{Region: cloudConn.Region, Client: cloudConn.SecurityClient, TagHandler: &tagHandler} return &handler, nil } func (cloudConn *AwsCloudConnection) CreateTagHandler() (irs.TagHandler, error) { - handler := ars.AwsTagHandler{cloudConn.Region, cloudConn.VMClient} + handler := ars.AwsTagHandler{Region: cloudConn.Region, Client: cloudConn.VMClient} return &handler, nil } +func (cloudConn *AwsCloudConnection) CreateAwsTagHandler() ars.AwsTagHandler { + handler := ars.AwsTagHandler{Region: cloudConn.Region, Client: cloudConn.VMClient} + return handler +} + /* func (cloudConn *AwsCloudConnection) CreateVNicHandler() (irs.VNicHandler, error) { cblogger.Info("Start") @@ -132,26 +141,30 @@ func (cloudConn *AwsCloudConnection) CreatePublicIPHandler() (irs.PublicIPHandle */ func (cloudConn *AwsCloudConnection) CreateVMSpecHandler() (irs.VMSpecHandler, error) { - handler := ars.AwsVmSpecHandler{cloudConn.Region, cloudConn.VmSpecClient} + handler := ars.AwsVmSpecHandler{Region: cloudConn.Region, Client: cloudConn.VmSpecClient} return &handler, nil } func (cloudConn *AwsCloudConnection) CreateNLBHandler() (irs.NLBHandler, error) { - handler := ars.AwsNLBHandler{cloudConn.Region, cloudConn.NLBClient, cloudConn.VMClient} + tagHandler := cloudConn.CreateAwsTagHandler() + handler := ars.AwsNLBHandler{Region: cloudConn.Region, Client: cloudConn.NLBClient, VMClient: cloudConn.VMClient, TagHandler: &tagHandler} return &handler, nil } func (cloudConn *AwsCloudConnection) CreateDiskHandler() (irs.DiskHandler, error) { - handler := ars.AwsDiskHandler{cloudConn.Region, cloudConn.DiskClient} + tagHandler := cloudConn.CreateAwsTagHandler() + handler := ars.AwsDiskHandler{Region: cloudConn.Region, Client: cloudConn.DiskClient, TagHandler: &tagHandler} return &handler, nil } func (cloudConn *AwsCloudConnection) CreateMyImageHandler() (irs.MyImageHandler, error) { - handler := ars.AwsMyImageHandler{cloudConn.Region, cloudConn.MyImageClient} + tagHandler := cloudConn.CreateAwsTagHandler() + handler := ars.AwsMyImageHandler{Region: cloudConn.Region, Client: cloudConn.MyImageClient, TagHandler: &tagHandler} return &handler, nil } func (cloudConn *AwsCloudConnection) CreateClusterHandler() (irs.ClusterHandler, error) { + tagHandler := cloudConn.CreateAwsTagHandler() cblogger.Info("CreateClusterHandler through") if cloudConn.MyImageClient == nil { cblogger.Info("cloudConn.MyImageClient is nil") @@ -168,21 +181,21 @@ func (cloudConn *AwsCloudConnection) CreateClusterHandler() (irs.ClusterHandler, if cloudConn.AutoScalingClient == nil { cblogger.Info("cloudConn.AutoScalingClient is nil") } - handler := ars.AwsClusterHandler{cloudConn.Region, cloudConn.EKSClient, cloudConn.VNetworkClient, cloudConn.IamClient, cloudConn.AutoScalingClient} + handler := ars.AwsClusterHandler{Region: cloudConn.Region, Client: cloudConn.EKSClient, EC2Client: cloudConn.VNetworkClient, Iam: cloudConn.IamClient, AutoScaling: cloudConn.AutoScalingClient, TagHandler: &tagHandler} return &handler, nil } func (cloudConn *AwsCloudConnection) CreateAnyCallHandler() (irs.AnyCallHandler, error) { - handler := ars.AwsAnyCallHandler{cloudConn.Region, cloudConn.CredentialInfo, cloudConn.AnyCallClient} + handler := ars.AwsAnyCallHandler{Region: cloudConn.Region, CredentialInfo: cloudConn.CredentialInfo, Client: cloudConn.AnyCallClient} return &handler, nil } func (cloudConn *AwsCloudConnection) CreateRegionZoneHandler() (irs.RegionZoneHandler, error) { - handler := ars.AwsRegionZoneHandler{cloudConn.Region, cloudConn.RegionZoneClient} + handler := ars.AwsRegionZoneHandler{Region: cloudConn.Region, Client: cloudConn.RegionZoneClient} return &handler, nil } func (cloudConn *AwsCloudConnection) CreatePriceInfoHandler() (irs.PriceInfoHandler, error) { - handler := ars.AwsPriceInfoHandler{cloudConn.Region, cloudConn.PriceInfoClient} + handler := ars.AwsPriceInfoHandler{Region: cloudConn.Region, Client: cloudConn.PriceInfoClient} return &handler, nil } diff --git a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go index 798186302..b2c0d5e4a 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go @@ -951,7 +951,7 @@ func handleVM() { //config := readConfigFile() //VmID := irs.IID{NameId: config.Aws.BaseName, SystemId: config.Aws.VmID} // VmID := irs.IID{SystemId: "i-0cea86282a9e2a569"} - VmID := irs.IID{SystemId: "i-0c70f696e5f8e690c"} + VmID := irs.IID{SystemId: "i-02ac1c4ff1d40815c"} for { fmt.Println("VM Management") @@ -2061,7 +2061,7 @@ func main() { // handleKeyPair() // handlePublicIP() // PublicIP 생성 후 conf // handleSecurity() - // handleVM() + handleVM() // handleImage() //AMI // handleVNic() //Lancard // handleVMSpec() @@ -2069,5 +2069,5 @@ func main() { // handleCluster() //handleRegionZone() //handlePriceInfo() - handleTag() + //handleTag() } diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go index f07a1b43a..bd0e86d82 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go @@ -24,6 +24,7 @@ type AwsClusterHandler struct { EC2Client *ec2.EC2 Iam *iam.IAM AutoScaling *autoscaling.AutoScaling + TagHandler *AwsTagHandler // 2024-07-18 TagHandler add } const ( diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/CommonHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/CommonHandler.go index 15bd583cf..fa0b01b29 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/CommonHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/CommonHandler.go @@ -10,7 +10,6 @@ import ( "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ec2" call "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/call-log" - idrv "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces" irs "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces/resources" ) @@ -769,140 +768,24 @@ func DescribeAvailabilityZones(client *ec2.EC2, AllRegionsBool bool) (*ec2.Descr // ---------------- RegionZone area end ----------// // ---------------- Tag area start ----------// -// Find tags by tag key or value -// resType: ALL | VPC, SUBNET, etc.,. -// keyword: The keyword to search for in the tag key or value. -// if you want to find all tags, set keyword to "" or "*". -func FindTagOrValue(client *ec2.EC2, regionInfo idrv.RegionInfo, resType irs.RSType, keyword string) ([]*irs.TagInfo, error) { - cblogger.Debugf("resType : [%s] / keyword : [%s]", resType, keyword) - - var filters []*ec2.Filter - - // Add resource type filter if resType is not ALL - if resType != irs.ALL { - if awsResType, ok := rsTypeToAwsResourceTypeMap[resType]; ok { - filters = append(filters, &ec2.Filter{ - Name: aws.String("resource-type"), - Values: []*string{ - aws.String(awsResType), - }, - }) - } else { - return nil, fmt.Errorf("unsupported resource type: %s", resType) - } - } - - tagInfoMap := make(map[string]*irs.TagInfo) - - // Function to process tags and add them to tagInfoMap - processTags := func(result *ec2.DescribeTagsOutput) { - if cblogger.Level.String() == "debug" { - cblogger.Debug(result) - //cblogger.Debug("=================================") - //spew.Dump(result) - //cblogger.Debug("=================================") - } - - for _, tag := range result.Tags { - resID := aws.StringValue(tag.ResourceId) - - awsResType := aws.StringValue(tag.ResourceType) - rType, exists := awsResourceTypeToRSTypeMap[awsResType] - if !exists { - //@TODO - 변환 실패한 리소스의 경우 UNKNOWN을 만들거나 에러 로그만 찍거나 결정 필요할 듯 - cblogger.Errorf("No RSType matching [%s] found.", awsResType) - - rType = irs.RSType(awsResType) // Use the raw AWS resource type if not mapped - } - - if _, exists := tagInfoMap[resID]; !exists { - tagInfoMap[resID] = &irs.TagInfo{ - ResType: rType, - ResIId: irs.IID{ - SystemId: resID, - }, - } - } - tagInfoMap[resID].TagList = append(tagInfoMap[resID].TagList, irs.KeyValue{ - Key: aws.StringValue(tag.Key), - Value: aws.StringValue(tag.Value), - }) - } - } - - // Search by tag-key if keyword is not empty or "*" - if keyword != "" && keyword != "*" { - keyInput := &ec2.DescribeTagsInput{ - Filters: append(filters, &ec2.Filter{ - Name: aws.String("tag-key"), - Values: []*string{ - aws.String(keyword), - }, - }), - } - - if cblogger.Level.String() == "debug" { - cblogger.Debug(keyInput) - } - - hiscallInfo := GetCallLogScheme(regionInfo, call.TAG, keyword, "FindTag(key):DescribeTags()") - start := call.Start() - - keyResult, err := client.DescribeTags(keyInput) - if err != nil { - LoggingError(hiscallInfo, err) - return nil, fmt.Errorf("failed to describe tags by key: %w", err) - } - LoggingInfo(hiscallInfo, start) - processTags(keyResult) - - valueInput := &ec2.DescribeTagsInput{ - Filters: append(filters, &ec2.Filter{ - Name: aws.String("tag-value"), - Values: []*string{ - aws.String(keyword), - }, - }), - } - - if cblogger.Level.String() == "debug" { - cblogger.Debug(valueInput) - } - - hiscallInfo2 := GetCallLogScheme(regionInfo, call.TAG, keyword, "FindTag(value):DescribeTags()") - start2 := call.Start() - - valueResult, err := client.DescribeTags(valueInput) - if err != nil { - LoggingError(hiscallInfo2, err) - return nil, fmt.Errorf("failed to describe tags by value: %w", err) - } - LoggingInfo(hiscallInfo2, start2) - processTags(valueResult) - } else { - // Search all tags if keyword is empty or "*" - input := &ec2.DescribeTagsInput{ - Filters: filters, - } - - hiscallInfo := GetCallLogScheme(regionInfo, call.TAG, keyword, "FindTag(all):DescribeTags()") - start := call.Start() - - result, err := client.DescribeTags(input) - if err != nil { - LoggingError(hiscallInfo, err) - return nil, fmt.Errorf("failed to describe tags: %w", err) - } - LoggingInfo(hiscallInfo, start) - processTags(result) - } - - var tagInfos []*irs.TagInfo - for _, tagInfo := range tagInfoMap { - tagInfos = append(tagInfos, tagInfo) +// This is a deprecated function, created as a reference for how to call it in various handlers. +// +// (exam) How to call from VMHandler +// +// vmInfo.TagList, _ = GetResourceTag(vmHandler, vmInfo.IId) +func GetResourceTag(handler interface{}, resIID irs.IID) ([]irs.KeyValue, error) { + var resType irs.RSType + + switch h := handler.(type) { + case *AwsVMHandler: + resType = irs.VM + return h.TagHandler.ListTag(resType, resIID) + case *AwsVPCHandler: + resType = irs.VPC + return h.TagHandler.ListTag(resType, resIID) + default: + return nil, fmt.Errorf("unsupported handler type") } - - return tagInfos, nil } // ---------------- Tag area end ----------// diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/DiskHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/DiskHandler.go index 36f4057bb..37e6cece8 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/DiskHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/DiskHandler.go @@ -19,8 +19,9 @@ import ( ) type AwsDiskHandler struct { - Region idrv.RegionInfo - Client *ec2.EC2 + Region idrv.RegionInfo + Client *ec2.EC2 + TagHandler *AwsTagHandler // 2024-07-18 TagHandler add } var VOLUME_TYPE = []string{"standard", "io1", "io2", "gp2", "gp3", "sc1", "st1"} // array 는 const 불가하여 변수로 처리. diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/KeyPairHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/KeyPairHandler.go index 337198191..02f2b5b45 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/KeyPairHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/KeyPairHandler.go @@ -20,6 +20,7 @@ type AwsKeyPairHandler struct { CredentialInfo idrv.CredentialInfo Region idrv.RegionInfo Client *ec2.EC2 + TagHandler *AwsTagHandler // 2024-07-18 TagHandler add } /* diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/MyImageHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/MyImageHandler.go index 8bdca4c6b..e34373b7d 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/MyImageHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/MyImageHandler.go @@ -22,8 +22,9 @@ import ( // CB-Spider MyImage 관리 기능은 VM Snapshot 실행과 결과로 생성된 VM Image(MyImage)를 관리하는 기능을 제공한다 // CB-Spider VM Snapshot은 운영 중인 VM의 상태와 VM에 Attach된 Data-Disk의 상태도 저장된다. type AwsMyImageHandler struct { - Region idrv.RegionInfo - Client *ec2.EC2 + Region idrv.RegionInfo + Client *ec2.EC2 + TagHandler *AwsTagHandler // 2024-07-18 TagHandler add } const ( diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/NLBHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/NLBHandler.go index b4e57b06d..318fd8556 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/NLBHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/NLBHandler.go @@ -23,8 +23,9 @@ import ( type AwsNLBHandler struct { Region idrv.RegionInfo //Client *elb.ELB - Client *elbv2.ELBV2 //elbV2 - VMClient *ec2.EC2 + Client *elbv2.ELBV2 //elbV2 + VMClient *ec2.EC2 + TagHandler *AwsTagHandler // 2024-07-18 TagHandler add } type TargetGroupInfo struct { diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/SecurityHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/SecurityHandler.go index 10aba285a..b14f6b7c6 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/SecurityHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/SecurityHandler.go @@ -28,8 +28,9 @@ import ( ) type AwsSecurityHandler struct { - Region idrv.RegionInfo - Client *ec2.EC2 + Region idrv.RegionInfo + Client *ec2.EC2 + TagHandler *AwsTagHandler // 2024-07-18 TagHandler add } // 2019-11-16부로 CB-Driver 전체 로직이 NameId 기반으로 변경됨. (보안 그룹은 그룹명으로 처리 가능하기 때문에 Name 태깅시 에러는 무시함) diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/VMHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/VMHandler.go index 6bc0bfe0b..152ec5752 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/VMHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/VMHandler.go @@ -27,8 +27,9 @@ import ( ) type AwsVMHandler struct { - Region idrv.RegionInfo - Client *ec2.EC2 + Region idrv.RegionInfo + Client *ec2.EC2 + TagHandler *AwsTagHandler // 2024-07-18 TagHandler add } func Connect(region string) *ec2.EC2 { @@ -1182,6 +1183,8 @@ func (vmHandler *AwsVMHandler) ExtractDescribeInstanceToVmInfo(instance *ec2.Ins } vmInfo.KeyValueList = keyValueList + vmInfo.TagList, _ = vmHandler.TagHandler.ListTag(irs.VM, vmInfo.IId) + //vmInfo.TagList, _ = GetResourceTag(vmHandler, vmInfo.IId) return vmInfo } diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/VPCHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/VPCHandler.go index ce148c44e..fa1bfd2f3 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/VPCHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/VPCHandler.go @@ -25,8 +25,9 @@ import ( ) type AwsVPCHandler struct { - Region idrv.RegionInfo - Client *ec2.EC2 + Region idrv.RegionInfo + Client *ec2.EC2 + TagHandler *AwsTagHandler // 2024-07-18 TagHandler add } func (VPCHandler *AwsVPCHandler) CreateVPC(vpcReqInfo irs.VPCReqInfo) (irs.VPCInfo, error) { @@ -175,6 +176,8 @@ func (VPCHandler *AwsVPCHandler) CreateVPC(vpcReqInfo irs.VPCReqInfo) (irs.VPCIn resSubnetList = append(resSubnetList, resSubnet) } retVpcInfo.SubnetInfoList = resSubnetList + + retVpcInfo.TagList, _ = VPCHandler.TagHandler.ListTag(irs.VM, retVpcInfo.IId) return retVpcInfo, nil } @@ -523,6 +526,7 @@ func (VPCHandler *AwsVPCHandler) GetVPC(vpcIID irs.IID) (irs.VPCInfo, error) { return awsVpcInfo, errSubnet } + awsVpcInfo.TagList, _ = VPCHandler.TagHandler.ListTag(irs.VM, awsVpcInfo.IId) return awsVpcInfo, nil } From cc6e296b3917cace37b0d98459a2ee02e4d0c103 Mon Sep 17 00:00:00 2001 From: dev4unet Date: Fri, 19 Jul 2024 10:27:58 +0000 Subject: [PATCH 15/32] Added Tag functionality to the creation and lookup of each handler. Testing in progress (VPC ok / Keypair ok) --- .../drivers/aws/main/Test_Resources.go | 29 ++++++++---- .../drivers/aws/resources/ClusterHandler.go | 4 ++ .../drivers/aws/resources/DiskHandler.go | 4 +- .../drivers/aws/resources/KeyPairHandler.go | 20 +++++++-- .../drivers/aws/resources/MyImageHandler.go | 2 + .../drivers/aws/resources/NLBHandler.go | 3 ++ .../drivers/aws/resources/SecurityHandler.go | 2 + .../drivers/aws/resources/TagHandler.go | 45 +++++++++++++++++++ .../drivers/aws/resources/VPCHandler.go | 32 +++++++++---- 9 files changed, 119 insertions(+), 22 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go index b2c0d5e4a..5c22326e9 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go @@ -467,6 +467,8 @@ func handleKeyPair() { //VmID := config.Aws.VmID keyPairName := "CB-KeyPairTest123123" + //keyPairName := "key-0a58c9a7b0a07a2d2" + //keyPairName := config.Aws.KeyName for { @@ -503,6 +505,8 @@ func handleKeyPair() { keyPairReqInfo := irs.KeyPairReqInfo{ IId: irs.IID{NameId: keyPairName}, //Name: keyPairName, + //TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}, {Key: "Name", Value: keyPairName+"123"}}, + TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}}, } result, err := KeyPairHandler.CreateKey(keyPairReqInfo) if err != nil { @@ -635,6 +639,8 @@ func handleVPC() { subnetReqInfo := irs.SubnetInfo{ IId: irs.IID{NameId: "AddTest-Subnet"}, IPv4_CIDR: "10.0.2.0/24", + //TagList: []irs.KeyValue{{Key: "Name1", Value: "Subnet Name Value1"}, {Key: "Name2", Value: "Subnet Name Value2"}, {Key: "Name", Value: "AddTest-Subnet123"}}, + TagList: []irs.KeyValue{{Key: "Name1", Value: "Subnet Name Value1"}, {Key: "Name2", Value: "Subnet Name Value2"}}, } subnetReqVpcInfo := irs.IID{SystemId: "vpc-00e513fd64a7d9972"} @@ -649,6 +655,8 @@ func handleVPC() { { IId: irs.IID{NameId: "New-CB-Subnet"}, IPv4_CIDR: "10.0.1.0/24", + TagList: []irs.KeyValue{{Key: "Name1", Value: "Subnet Name Value1"}, {Key: "Name2", Value: "Subnet Name Value2"}, {Key: "Name", Value: "AddTest-Subnet123"}}, + //TagList: []irs.KeyValue{{Key: "Name1", Value: "Subnet Name Value1"}, {Key: "Name2", Value: "Subnet Name Value2"}}, }, /* { @@ -661,6 +669,8 @@ func handleVPC() { //Name: "CB-VNet-Subnet", // 웹 도구 등 외부에서 전달 받지 않고 드라이버 내부적으로 자동 구현때문에 사용하지 않음. //CidrBlock: "10.0.0.0/16", //CidrBlock: "192.168.0.0/16", + TagList: []irs.KeyValue{{Key: "Name1", Value: "Subnet Name Value1"}, {Key: "Name2", Value: "Subnet Name Value2"}, {Key: "Name", Value: "New-CB-VPC123"}}, + //TagList: []irs.KeyValue{{Key: "Name1", Value: "VPC Name Value1"}, {Key: "Name2", Value: "VPC Name Value2"}}, } reqSubnetId := irs.IID{SystemId: "vpc-04f6de5c2af880978"} @@ -1787,12 +1797,14 @@ func handleTag() { } handler := ResourceHandler.(irs.TagHandler) - var reqType irs.RSType = irs.VM - reqIID := irs.IID{SystemId: "i-02ac1c4ff1d40815c"} + var reqType irs.RSType = irs.KEY + //reqIID := irs.IID{SystemId: "i-02ac1c4ff1d40815c"} + reqIID := irs.IID{SystemId: "CB-KeyPairTest123123"} + reqTag := irs.KeyValue{Key: "tag3", Value: "tag3 test"} reqKey := "tag3" reqKey = "" - reqType = irs.ALL + //reqType = irs.ALL for { fmt.Println("TagHandler Management") @@ -2057,17 +2069,18 @@ func readConfigFile() Config { } func main() { + handleKeyPair() + handleTag() //handleVPC() - // handleKeyPair() // handlePublicIP() // PublicIP 생성 후 conf - // handleSecurity() + handleSecurity() handleVM() // handleImage() //AMI // handleVNic() //Lancard // handleVMSpec() - // handleNLB() - // handleCluster() + handleNLB() + handleCluster() //handleRegionZone() //handlePriceInfo() - //handleTag() + handleTag() } diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go index bd0e86d82..6b4f6c121 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/ClusterHandler.go @@ -178,6 +178,8 @@ func (ClusterHandler *AwsClusterHandler) CreateCluster(clusterReqInfo irs.Cluste return irs.ClusterInfo{}, errClusterInfo } clusterInfo.IId.NameId = clusterReqInfo.IId.NameId + clusterInfo.TagList, _ = ClusterHandler.TagHandler.ListTag(irs.CLUSTER, clusterInfo.IId) + return clusterInfo, nil } @@ -393,6 +395,8 @@ func (ClusterHandler *AwsClusterHandler) GetCluster(clusterIID irs.IID) (irs.Clu } clusterInfo.KeyValueList = keyValueList + clusterInfo.TagList, _ = ClusterHandler.TagHandler.ListTag(irs.CLUSTER, clusterInfo.IId) + //노드 그룹 처리 resNodeGroupList, errNodeGroup := ClusterHandler.ListNodeGroup(clusterInfo.IId) if errNodeGroup != nil { diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/DiskHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/DiskHandler.go index 37e6cece8..d479554b4 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/DiskHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/DiskHandler.go @@ -197,7 +197,7 @@ func (DiskHandler *AwsDiskHandler) GetDisk(diskIID irs.IID) (irs.DiskInfo, error } calllogger.Info(call.String(hiscallInfo)) - diskInfo, err := DiskHandler.convertVolumeInfoToDiskInfo(result.Volumes[0]) + diskInfo, _ := DiskHandler.convertVolumeInfoToDiskInfo(result.Volumes[0]) return diskInfo, nil } @@ -910,5 +910,7 @@ func (DiskHandler *AwsDiskHandler) convertVolumeInfoToDiskInfo(volumeInfo *ec2.V cblogger.Debug("keyvalue2") cblogger.Debug(diskInfo) + diskInfo.TagList, _ = DiskHandler.TagHandler.ListTag(irs.DISK, diskInfo.IId) + return diskInfo, nil } diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/KeyPairHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/KeyPairHandler.go index 02f2b5b45..e5639c227 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/KeyPairHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/KeyPairHandler.go @@ -13,6 +13,7 @@ import ( call "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/call-log" idrv "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces" irs "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces/resources" + "github.com/davecgh/go-spew/spew" //_ "github.com/davecgh/go-spew/spew" ) @@ -108,7 +109,7 @@ func (keyPairHandler *AwsKeyPairHandler) CreateKey(keyPairReqInfo irs.KeyPairReq */ // Convert TagList to TagSpecifications - tagSpecifications, err := ConvertTagListToTagSpecifications("key-pair", keyPairReqInfo.TagList) + tagSpecifications, err := ConvertTagListToTagSpecifications("key-pair", keyPairReqInfo.TagList, keyPairReqInfo.IId.NameId) if err != nil { return irs.KeyPairInfo{}, fmt.Errorf("failed to convert tag list: %w", err) } @@ -125,12 +126,16 @@ func (keyPairHandler *AwsKeyPairHandler) CreateKey(keyPairReqInfo irs.KeyPairReq ErrorMSG: "", } callLogStart := call.Start() - // Creates a new key pair with the given name - result, err := keyPairHandler.Client.CreateKeyPair(&ec2.CreateKeyPairInput{ + + input := &ec2.CreateKeyPairInput{ //KeyName: aws.String(keyPairReqInfo.Name), KeyName: aws.String(keyPairReqInfo.IId.NameId), TagSpecifications: tagSpecifications, - }) + } + // Creates a new key pair with the given name + result, err := keyPairHandler.Client.CreateKeyPair(input) + spew.Dump(result) + callLogInfo.ElapsedTime = call.Elapsed(callLogStart) if err != nil { @@ -204,6 +209,9 @@ func (keyPairHandler *AwsKeyPairHandler) CreateKey(keyPairReqInfo irs.KeyPairReq return irs.KeyPairInfo{}, err } */ + + keyPairInfo.TagList, _ = keyPairHandler.TagHandler.ListTag(irs.KEY, keyPairInfo.IId) + return keyPairInfo, nil } @@ -245,6 +253,7 @@ func (keyPairHandler *AwsKeyPairHandler) GetKey(keyIID irs.IID) (irs.KeyPairInfo callLogStart := call.Start() result, err := keyPairHandler.Client.DescribeKeyPairs(input) + spew.Dump(result) callLogInfo.ElapsedTime = call.Elapsed(callLogStart) cblogger.Debug("result : ", result) cblogger.Debug("err : ", err) @@ -278,6 +287,9 @@ func (keyPairHandler *AwsKeyPairHandler) GetKey(keyIID irs.IID) (irs.KeyPairInfo return irs.KeyPairInfo{}, errKeyPair } + keyPairInfo.TagList, _ = keyPairHandler.TagHandler.ListTag(irs.KEY, keyPairInfo.IId) + spew.Dump(keyPairInfo.TagList) + cblogger.Debug(keyPairInfo) return keyPairInfo, nil } else { diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/MyImageHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/MyImageHandler.go index e34373b7d..80c709f88 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/MyImageHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/MyImageHandler.go @@ -407,6 +407,8 @@ func (ImageHandler *AwsMyImageHandler) GetMyImage(myImageIID irs.IID) (irs.MyIma return irs.MyImageInfo{}, err } + returnMyImage.TagList, _ = ImageHandler.TagHandler.ListTag(irs.MYIMAGE, returnMyImage.IId) + return returnMyImage, nil } diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/NLBHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/NLBHandler.go index 318fd8556..44bac573a 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/NLBHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/NLBHandler.go @@ -813,6 +813,9 @@ func (NLBHandler *AwsNLBHandler) GetNLB(nlbIID irs.IID) (irs.NLBInfo, error) { if errInfo != nil { return irs.NLBInfo{}, errInfo } + + nlbInfo.TagList, _ = NLBHandler.TagHandler.ListTag(irs.NLB, nlbInfo.IId) + return nlbInfo, nil } else { return irs.NLBInfo{}, errors.New("InvalidNLBArn.NotFound: The NLB Arn '" + nlbIID.SystemId + "' does not exist") diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/SecurityHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/SecurityHandler.go index b14f6b7c6..40cd26dba 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/SecurityHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/SecurityHandler.go @@ -411,6 +411,8 @@ func (securityHandler *AwsSecurityHandler) GetSecurity(securityIID irs.IID) (irs if len(result.SecurityGroups) > 0 { securityInfo := ExtractSecurityInfo(result.SecurityGroups[0]) + securityInfo.TagList, _ = securityHandler.TagHandler.ListTag(irs.SG, securityInfo.IId) + return securityInfo, nil } else { //return irs.SecurityInfo{}, errors.New("[" + securityNameId + "] 정보를 찾을 수 없습니다.") diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go index 64aab4508..23957e90a 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go @@ -20,6 +20,7 @@ import ( "fmt" "github.com/aws/aws-sdk-go/aws" + "github.com/davecgh/go-spew/spew" //"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ec2" @@ -72,6 +73,8 @@ func (tagHandler *AwsTagHandler) AddTag(resType irs.RSType, resIID irs.IID, tag return irs.KeyValue{}, errors.New(msg) } + resIID = tagHandler.GetRealResourceId(resType, resIID) // fix some resource id error + hiscallInfo := GetCallLogScheme(tagHandler.Region, call.TAG, resIID.SystemId, "CreateTags()") start := call.Start() @@ -109,6 +112,7 @@ func (tagHandler *AwsTagHandler) ListTag(resType irs.RSType, resIID irs.IID) ([] return nil, errors.New(msg) } + resIID = tagHandler.GetRealResourceId(resType, resIID) // fix some resource id error input := &ec2.DescribeTagsInput{ Filters: []*ec2.Filter{ { @@ -159,6 +163,7 @@ func (tagHandler *AwsTagHandler) GetTag(resType irs.RSType, resIID irs.IID, key cblogger.Error(msg) return irs.KeyValue{}, errors.New(msg) } + resIID = tagHandler.GetRealResourceId(resType, resIID) // fix some resource id error input := &ec2.DescribeTagsInput{ Filters: []*ec2.Filter{ @@ -217,6 +222,40 @@ func (tagHandler *AwsTagHandler) GetTag(resType irs.RSType, resIID irs.IID, key return retTag, nil } +// Handles targets that have a Name-based to Id conversion task, like Keypair. +// Keypair should use id, not name. +func (tagHandler *AwsTagHandler) GetRealResourceId(resType irs.RSType, resIID irs.IID) irs.IID { + + cblogger.Debugf("resType : [%s] / resIID : [%s]", resType, resIID.SystemId) + + if resType != irs.KEY { + return resIID + } + + // + // Keypair should use id, not name, when using Tag-related APIs. + // + input := &ec2.DescribeKeyPairsInput{ + KeyNames: []*string{ + aws.String(resIID.SystemId), + }, + } + + result, err := tagHandler.Client.DescribeKeyPairs(input) + spew.Dump(result) + if err != nil { + cblogger.Error(err) + return resIID + } + + if len(result.KeyPairs) > 0 { + newIID := irs.IID{NameId: *result.KeyPairs[0].KeyName, SystemId: *result.KeyPairs[0].KeyPairId} + return newIID + } + + return resIID +} + func (tagHandler *AwsTagHandler) RemoveTag(resType irs.RSType, resIID irs.IID, key string) (bool, error) { cblogger.Debugf("Req resTyp:[%s] / resIID:[%s] / key:[%s]", resType, resIID, key) @@ -225,6 +264,7 @@ func (tagHandler *AwsTagHandler) RemoveTag(resType irs.RSType, resIID irs.IID, k cblogger.Error(msg) return false, errors.New(msg) } + resIID = tagHandler.GetRealResourceId(resType, resIID) // fix some resource id error input := &ec2.DeleteTagsInput{ Resources: []*string{ @@ -269,6 +309,11 @@ func (tagHandler *AwsTagHandler) FindTag(resType irs.RSType, keyword string) ([] var filters []*ec2.Filter + if resType == irs.KEY { + resIID := tagHandler.GetRealResourceId(resType, irs.IID{SystemId: keyword}) // fix some resource id error + keyword = resIID.SystemId + } + // Add resource type filter if resType is not ALL if resType != irs.ALL { if awsResType, ok := rsTypeToAwsResourceTypeMap[resType]; ok { diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/VPCHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/VPCHandler.go index fa1bfd2f3..29e399086 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/VPCHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/VPCHandler.go @@ -298,18 +298,25 @@ func (VPCHandler *AwsVPCHandler) CreateSubnet(vpcId string, reqSubnetInfo irs.Su if reqSubnetInfo.IId.SystemId != "" { vpcInfo, errVpcInfo := VPCHandler.GetSubnet(reqSubnetInfo.IId.SystemId) if errVpcInfo == nil { - cblogger.Errorf("[%S] subnet already exists. returns an error without creating it.", reqSubnetInfo.IId.SystemId) + cblogger.Errorf("[%s] subnet already exists. returns an error without creating it", reqSubnetInfo.IId.SystemId) cblogger.Info(vpcInfo) return vpcInfo, errors.New("InvalidVNetwork.Duplicate: The Subnet '" + reqSubnetInfo.IId.SystemId + "' already exists.") } } - //서브넷 생성 + // Convert TagList to TagSpecifications + tagSpecifications, err := ConvertTagListToTagSpecifications("subnet", reqSubnetInfo.TagList, reqSubnetInfo.IId.NameId) + if err != nil { + return irs.SubnetInfo{}, fmt.Errorf("failed to convert tag list: %w", err) + } + + // Create subnet input with tag specifications input := &ec2.CreateSubnetInput{ CidrBlock: aws.String(reqSubnetInfo.IPv4_CIDR), VpcId: aws.String(vpcId), //AvailabilityZoneId: aws.String(zoneId), //use1-az1, use1-az2, use1-az3, use1-az4, use1-az5, use1-az6 - AvailabilityZone: aws.String(zoneId), + AvailabilityZone: aws.String(zoneId), + TagSpecifications: tagSpecifications, } // logger for HisCall @@ -351,13 +358,16 @@ func (VPCHandler *AwsVPCHandler) CreateSubnet(vpcId string, reqSubnetInfo irs.Su //vNetworkInfo := irs.VNetworkInfo{} vNetworkInfo := ExtractSubnetDescribeInfo(result.Subnet) + vNetworkInfo.TagList, _ = VPCHandler.TagHandler.ListTag(irs.SUBNET, vNetworkInfo.IId) - //Subnet Name 태깅 - if SetNameTag(VPCHandler.Client, *result.Subnet.SubnetId, reqSubnetInfo.IId.NameId) { - cblogger.Infof("set %s Name to subnet", reqSubnetInfo.IId.NameId) - } else { - cblogger.Errorf("set %s Name to subnet failed", reqSubnetInfo.IId.NameId) - } + /* + //Subnet Name 태깅 + if SetNameTag(VPCHandler.Client, *result.Subnet.SubnetId, reqSubnetInfo.IId.NameId) { + cblogger.Infof("set %s Name to subnet", reqSubnetInfo.IId.NameId) + } else { + cblogger.Errorf("set %s Name to subnet failed", reqSubnetInfo.IId.NameId) + } + */ vNetworkInfo.IId.NameId = reqSubnetInfo.IId.NameId @@ -985,6 +995,8 @@ func (VPCHandler *AwsVPCHandler) ListSubnet(vpcId string) ([]irs.SubnetInfo, err for _, curSubnet := range result.Subnets { cblogger.Infof("Retrieve [%s] Subnet info", *curSubnet.SubnetId) arrSubnetInfo := ExtractSubnetDescribeInfo(curSubnet) + arrSubnetInfo.TagList, _ = VPCHandler.TagHandler.ListTag(irs.SUBNET, arrSubnetInfo.IId) + //arrSubnetInfo, errSubnet := VPCHandler.GetSubnet(*curSubnet.SubnetId) /* if errSubnet != nil { @@ -1046,6 +1058,8 @@ func (VPCHandler *AwsVPCHandler) GetSubnet(reqSubnetId string) (irs.SubnetInfo, if !reflect.ValueOf(result.Subnets).IsNil() { retSubnetInfo := ExtractSubnetDescribeInfo(result.Subnets[0]) + retSubnetInfo.TagList, _ = VPCHandler.TagHandler.ListTag(irs.SUBNET, retSubnetInfo.IId) + return retSubnetInfo, nil } else { return irs.SubnetInfo{}, errors.New("InvalidSubnet.NotFound: The CBVnetwork '" + reqSubnetId + "' does not exist") From d785886d090c547695498a3a2aaf635895d27121 Mon Sep 17 00:00:00 2001 From: dev4unet Date: Mon, 22 Jul 2024 10:38:36 +0000 Subject: [PATCH 16/32] Complete NLB Tag Test & Add NLB Search to FindTag --- .../drivers/aws/connect/AwsCloudConnection.go | 4 +- .../drivers/aws/main/Test_Resources.go | 50 ++--- .../drivers/aws/resources/TagHandler.go | 173 ++++++++++++++++-- 3 files changed, 191 insertions(+), 36 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/aws/connect/AwsCloudConnection.go b/cloud-control-manager/cloud-driver/drivers/aws/connect/AwsCloudConnection.go index 4530a7323..424000f90 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/connect/AwsCloudConnection.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/connect/AwsCloudConnection.go @@ -115,12 +115,12 @@ func (cloudConn *AwsCloudConnection) CreateSecurityHandler() (irs.SecurityHandle } func (cloudConn *AwsCloudConnection) CreateTagHandler() (irs.TagHandler, error) { - handler := ars.AwsTagHandler{Region: cloudConn.Region, Client: cloudConn.VMClient} + handler := ars.AwsTagHandler{Region: cloudConn.Region, Client: cloudConn.VMClient, NLBClient: cloudConn.NLBClient} return &handler, nil } func (cloudConn *AwsCloudConnection) CreateAwsTagHandler() ars.AwsTagHandler { - handler := ars.AwsTagHandler{Region: cloudConn.Region, Client: cloudConn.VMClient} + handler := ars.AwsTagHandler{Region: cloudConn.Region, Client: cloudConn.VMClient, NLBClient: cloudConn.NLBClient} return handler } diff --git a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go index 5c22326e9..0e0f8a51a 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go @@ -50,9 +50,9 @@ func handleSecurity() { //config := readConfigFile() //VmID := config.Aws.VmID - securityName := "CB-SecurityAddTest1" + securityName := "CB-SecurityTagTest" securityId := "sg-0d6a2bb960481ce68" - vpcId := "vpc-c0479cab" + vpcId := "vpc-0a115f43d4fcbab36" //New-CB-VPC for { fmt.Println("Security Management") @@ -78,7 +78,7 @@ func handleSecurity() { case 1: result, err := handler.ListSecurity() if err != nil { - cblogger.Infof(" Security List Lookup Failed : ", err) + cblogger.Info(" Security List Lookup Failed : ", err) } else { cblogger.Info("Security List Lookup Result") cblogger.Info(result) @@ -94,6 +94,8 @@ func handleSecurity() { securityReqInfo := irs.SecurityReqInfo{ IId: irs.IID{NameId: securityName}, VpcIID: irs.IID{SystemId: vpcId}, + //TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}, {Key: "Name", Value: securityName+"123"}}, + TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}}, SecurityRules: &[]irs.SecurityRuleInfo{ //보안 정책 설정 //CIDR 테스트 { @@ -193,7 +195,7 @@ func handleSecurity() { if err != nil { cblogger.Infof(securityId, " Security Delete Failed : ", err) } else { - cblogger.Infof("[%s] Security Delete Result : [%s]", securityId, result) + cblogger.Infof("[%s] Security Delete Result : [%t]", securityId, result) } case 5: @@ -466,9 +468,7 @@ func handleKeyPair() { //config := readConfigFile() //VmID := config.Aws.VmID - keyPairName := "CB-KeyPairTest123123" - //keyPairName := "key-0a58c9a7b0a07a2d2" - + keyPairName := "CB-KeyPairTagTest" //keyPairName := config.Aws.KeyName for { @@ -505,7 +505,7 @@ func handleKeyPair() { keyPairReqInfo := irs.KeyPairReqInfo{ IId: irs.IID{NameId: keyPairName}, //Name: keyPairName, - //TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}, {Key: "Name", Value: keyPairName+"123"}}, + //TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}, {Key: "Name", Value: keyPairName + "123"}}, TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}}, } result, err := KeyPairHandler.CreateKey(keyPairReqInfo) @@ -990,17 +990,19 @@ func handleVM() { case 1: vmReqInfo := irs.VMReqInfo{ - IId: irs.IID{NameId: "mcloud-barista-windows-test"}, + IId: irs.IID{NameId: "mcloud-barista-tag-test"}, + TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}, {Key: "Name", Value: "mcloud-barista-tag-test123"}}, + //TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}}, //ImageIID: irs.IID{SystemId: "ami-001b6f8703b50e077"}, //centos-stable-7.2003.13-ebs-202005201235 - //ImageIID: irs.IID{SystemId: "ami-059b6d3840b03d6dd"}, //Ubuntu Server 20.04 LTS (HVM) + ImageIID: irs.IID{SystemId: "ami-056a29f2eddc40520"}, //Ubuntu Server 22.04 LTS (HVM), SSD Volume Type //ImageIID: irs.IID{SystemId: "ami-09e67e426f25ce0d7"}, //Ubuntu Server 20.04 LTS (HVM) - 버지니아 북부 리전 //ImageIID: irs.IID{SystemId: "ami-059b6d3840b03d6dd"}, //Ubuntu Server 20.04 LTS (HVM) //ImageIID: irs.IID{SystemId: "ami-0fe22bffdec36361c"}, //Ubuntu Server 18.04 LTS (HVM) - Japan 리전 - ImageIID: irs.IID{SystemId: "ami-093f427eb324bb754"}, //Microsoft Windows Server 2012 R2 RTM 64-bit Locale English AMI provided by Amazon - Japan 리전 - SubnetIID: irs.IID{SystemId: "subnet-0a6ca346752be1ca4"}, - SecurityGroupIIDs: []irs.IID{{SystemId: "sg-0f4532a525ad09de1"}}, //3389 RDP 포트 Open + //ImageIID: irs.IID{SystemId: "ami-093f427eb324bb754"}, //Microsoft Windows Server 2012 R2 RTM 64-bit Locale English AMI provided by Amazon - Japan 리전 + SubnetIID: irs.IID{SystemId: "subnet-02127b9d8c84f7440"}, + SecurityGroupIIDs: []irs.IID{{SystemId: "sg-0209d9dc23ebd4cdd"}}, //3389 RDP 포트 Open VMSpecName: "t2.micro", - KeyPairIID: irs.IID{SystemId: "japan-test"}, + KeyPairIID: irs.IID{SystemId: "CB-KeyPairTagTest"}, VMUserPasswd: "1234qwer!@#$", //윈도우즈용 비밀번호 RootDiskType: "standard", //gp2/standard/io1/io2/sc1/st1/gp3 @@ -1236,10 +1238,13 @@ func handleNLB() { nlbReqInfo := irs.NLBInfo{ IId: irs.IID{NameId: "cb-nlb-test01"}, - VpcIID: irs.IID{SystemId: "vpc-0c4d36a3ac3924419"}, + VpcIID: irs.IID{SystemId: "vpc-0a115f43d4fcbab36"}, Type: "PUBLIC", Scope: "REGION", + TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}, {Key: "Name", Value: "cb-nlb-test01123"}}, + //TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}}, + Listener: irs.ListenerInfo{ Protocol: "TCP", // AWS NLB : TCP, TLS, UDP, or TCP_UDP //IP: "", @@ -1249,7 +1254,7 @@ func handleNLB() { VMGroup: irs.VMGroupInfo{ Protocol: "TCP", //TCP|UDP|HTTP|HTTPS Port: "22", //1-65535 - VMs: &[]irs.IID{irs.IID{SystemId: "i-0dcbcbeadbb14212f"}, irs.IID{SystemId: "i-0cba8efe123ab0b42"}, irs.IID{SystemId: "i-010c858cbe5b6fe93"}}, + VMs: &[]irs.IID{irs.IID{SystemId: "i-0c65033e158e0fd99"}}, }, HealthChecker: irs.HealthCheckerInfo{ @@ -1803,8 +1808,10 @@ func handleTag() { reqTag := irs.KeyValue{Key: "tag3", Value: "tag3 test"} reqKey := "tag3" + reqKey = "CB-KeyPairTagTest" + reqKey = "cb-nlb-test01123" reqKey = "" - //reqType = irs.ALL + reqType = irs.ALL for { fmt.Println("TagHandler Management") @@ -2069,12 +2076,13 @@ func readConfigFile() Config { } func main() { - handleKeyPair() handleTag() - //handleVPC() // handlePublicIP() // PublicIP 생성 후 conf - handleSecurity() - handleVM() + + //handleKeyPair() + //handleVPC() + //handleSecurity() + //handleVM() // handleImage() //AMI // handleVNic() //Lancard // handleVMSpec() diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go index 23957e90a..76cdc47c2 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go @@ -24,14 +24,17 @@ import ( //"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/aws/aws-sdk-go/service/elbv2" + call "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/call-log" idrv "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces" irs "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces/resources" ) type AwsTagHandler struct { - Region idrv.RegionInfo - Client *ec2.EC2 + Region idrv.RegionInfo + Client *ec2.EC2 + NLBClient *elbv2.ELBV2 } // Map of RSType to AWS resource types @@ -103,6 +106,88 @@ func (tagHandler *AwsTagHandler) AddTag(resType irs.RSType, resIID irs.IID, tag return tag, nil } +func (tagHandler *AwsTagHandler) GetAllNLBTags() ([]*irs.TagInfo, error) { + // Step 1: List all load balancers and store their ARNs and Names + lbArnToName := make(map[string]string) + + err := tagHandler.NLBClient.DescribeLoadBalancersPages(&elbv2.DescribeLoadBalancersInput{}, func(page *elbv2.DescribeLoadBalancersOutput, lastPage bool) bool { + for _, lb := range page.LoadBalancers { + lbArnToName[*lb.LoadBalancerArn] = *lb.LoadBalancerName + } + return !lastPage + }) + + if err != nil { + return nil, fmt.Errorf("failed to describe load balancers: %w", err) + } + + if len(lbArnToName) == 0 { + return nil, fmt.Errorf("no load balancers found") + } + + // Step 2: Describe tags for each load balancer using the GetNLBTags function + var allTagInfos []*irs.TagInfo + + for arn, name := range lbArnToName { + resIID := irs.IID{ + NameId: name, + SystemId: arn, + } + + tagInfos, err := tagHandler.GetNLBTags(resIID) + if err != nil { + return nil, fmt.Errorf("failed to get tags for load balancer %s: %w", arn, err) + } + + // Process only if Tag exists + if len(tagInfos) == 0 { + continue + } + + // Convert tags into TagInfo with the correct ResType + tagInfo := &irs.TagInfo{ + ResType: irs.NLB, + ResIId: resIID, + TagList: tagInfos, + } + + allTagInfos = append(allTagInfos, tagInfo) + } + + return allTagInfos, nil +} + +func (tagHandler *AwsTagHandler) GetNLBTags(resIID irs.IID) ([]irs.KeyValue, error) { + input := &elbv2.DescribeTagsInput{ + ResourceArns: []*string{ + aws.String(resIID.SystemId), + }, + } + + result, err := tagHandler.NLBClient.DescribeTags(input) + if err != nil { + return nil, fmt.Errorf("failed to describe load balancer tags: %w", err) + } + + if len(result.TagDescriptions) == 0 { + return nil, fmt.Errorf("no tags found for load balancer: %s", resIID.SystemId) + } + + if cblogger.Level.String() == "debug" { + cblogger.Debug(result) + } + + var retTagList []irs.KeyValue + for _, tag := range result.TagDescriptions[0].Tags { + retTagList = append(retTagList, irs.KeyValue{ + Key: aws.StringValue(tag.Key), + Value: aws.StringValue(tag.Value), + }) + } + + return retTagList, nil +} + func (tagHandler *AwsTagHandler) ListTag(resType irs.RSType, resIID irs.IID) ([]irs.KeyValue, error) { cblogger.Debugf("Req resTyp:[%s] / resIID:[%s]", resType, resIID) @@ -112,6 +197,10 @@ func (tagHandler *AwsTagHandler) ListTag(resType irs.RSType, resIID irs.IID) ([] return nil, errors.New(msg) } + if resType == irs.NLB { + return tagHandler.GetNLBTags(resIID) + } + resIID = tagHandler.GetRealResourceId(resType, resIID) // fix some resource id error input := &ec2.DescribeTagsInput{ Filters: []*ec2.Filter{ @@ -140,7 +229,7 @@ func (tagHandler *AwsTagHandler) ListTag(resType irs.RSType, resIID irs.IID) ([] LoggingInfo(hiscallInfo, start) if cblogger.Level.String() == "debug" { - cblogger.Info(result) + cblogger.Debug(result) } var retTagList []irs.KeyValue @@ -300,6 +389,48 @@ func (tagHandler *AwsTagHandler) RemoveTag(resType irs.RSType, resIID irs.IID, k return true, nil } +// Extracts a list of Key or Value tags corresponding to keyword from the tagInfos array. +func (tagHandler *AwsTagHandler) ExtractTagKeyValue(tagInfos []*irs.TagInfo, keyword string) []*irs.TagInfo { + var matchingTagInfos []*irs.TagInfo + cblogger.Debugf("tagInfos count : [%d] / keyword : [%s]", len(tagInfos), keyword) + if cblogger.Level.String() == "debug" { + spew.Dump(tagInfos) + } + + /* + for _, tagInfo := range tagInfos { + for _, kv := range tagInfo.TagList { + if kv.Key == keyword || kv.Value == keyword { + matchingTagInfos = append(matchingTagInfos, tagInfo) + break // If any match, add that tagInfo and move on to the next tagInfo + } + } + } + */ + + // The DescribeTags() API used by FindTag() only includes matching Keys, so we modified it with the same logic. + for _, tagInfo := range tagInfos { + var filteredTagList []irs.KeyValue + + for _, kv := range tagInfo.TagList { + if kv.Key == keyword || kv.Value == keyword { + filteredTagList = append(filteredTagList, kv) + } + } + + if len(filteredTagList) > 0 { + matchingTagInfo := &irs.TagInfo{ + ResType: tagInfo.ResType, + ResIId: tagInfo.ResIId, + TagList: filteredTagList, + KeyValueList: tagInfo.KeyValueList, + } + matchingTagInfos = append(matchingTagInfos, matchingTagInfo) + } + } + return matchingTagInfos +} + // Find tags by tag key or value // resType: ALL | VPC, SUBNET, etc.,. // keyword: The keyword to search for in the tag key or value. @@ -307,15 +438,22 @@ func (tagHandler *AwsTagHandler) RemoveTag(resType irs.RSType, resIID irs.IID, k func (tagHandler *AwsTagHandler) FindTag(resType irs.RSType, keyword string) ([]*irs.TagInfo, error) { cblogger.Debugf("resType : [%s] / keyword : [%s]", resType, keyword) + var tagInfos []*irs.TagInfo var filters []*ec2.Filter - if resType == irs.KEY { - resIID := tagHandler.GetRealResourceId(resType, irs.IID{SystemId: keyword}) // fix some resource id error - keyword = resIID.SystemId - } - // Add resource type filter if resType is not ALL if resType != irs.ALL { + if resType == irs.NLB { + // Add a list of NLB Tags if this is a all search + if keyword == "" || keyword == "*" { + return tagHandler.GetAllNLBTags() + } else { + nlbTaginfos, _ := tagHandler.GetAllNLBTags() + //spew.Dump(nlbTaginfos) + return tagHandler.ExtractTagKeyValue(nlbTaginfos, keyword), nil + } + } + if awsResType, ok := rsTypeToAwsResourceTypeMap[resType]; ok { filters = append(filters, &ec2.Filter{ Name: aws.String("resource-type"), @@ -333,10 +471,10 @@ func (tagHandler *AwsTagHandler) FindTag(resType irs.RSType, keyword string) ([] // Function to process tags and add them to tagInfoMap processTags := func(result *ec2.DescribeTagsOutput) { if cblogger.Level.String() == "debug" { - cblogger.Debug(result) - //cblogger.Debug("=================================") - //spew.Dump(result) - //cblogger.Debug("=================================") + //cblogger.Debug(result) + cblogger.Debug("=================================") + spew.Dump(result) + cblogger.Debug("=================================") } for _, tag := range result.Tags { @@ -433,10 +571,19 @@ func (tagHandler *AwsTagHandler) FindTag(resType irs.RSType, keyword string) ([] processTags(result) } - var tagInfos []*irs.TagInfo + //var tagInfos []*irs.TagInfo for _, tagInfo := range tagInfoMap { tagInfos = append(tagInfos, tagInfo) } + // Add a list of NLB Tags if this is a all search + if resType == irs.ALL { + nlbTaginfos, _ := tagHandler.GetAllNLBTags() + if keyword != "" && keyword != "*" { + nlbTaginfos = tagHandler.ExtractTagKeyValue(nlbTaginfos, keyword) + } + tagInfos = append(tagInfos, nlbTaginfos...) + } + return tagInfos, nil } From e5ad56fcf0c001f5514bffa02be2c0716c32cd59 Mon Sep 17 00:00:00 2001 From: innodreamer Date: Tue, 23 Jul 2024 21:24:26 +0900 Subject: [PATCH 17/32] Unify NCP VM Creating Status (Booting / Setting up -> Creating) --- .../drivers/ncp/resources/VMHandler.go | 107 +++++------------- 1 file changed, 28 insertions(+), 79 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/ncp/resources/VMHandler.go b/cloud-control-manager/cloud-driver/drivers/ncp/resources/VMHandler.go index 5cf94d903..24d716035 100644 --- a/cloud-control-manager/cloud-driver/drivers/ncp/resources/VMHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ncp/resources/VMHandler.go @@ -185,7 +185,7 @@ func (vmHandler *NcpVMHandler) StartVM(vmReqInfo irs.VMReqInfo) (irs.VMInfo, err } } } - cblogger.Info("### Succeeded in Creating Init UserData!!") + // cblogger.Info("### Succeeded in Creating Init UserData!!") // cblogger.Infof("Init UserData : [%s]", *initUserData) // Note) NCP에서는 UserData용 string에 Base64 인코딩 불필요 // cmdStringBase64 := base64.StdEncoding.EncodeToString([]byte(cmdString)) @@ -239,7 +239,7 @@ func (vmHandler *NcpVMHandler) StartVM(vmReqInfo irs.VMReqInfo) (irs.VMInfo, err cblogger.Info("# createTagResult : ", createTagResult) // Wait while being created to get VM information. - curStatus, statusErr := vmHandler.WaitToGetInfo(newVMIID) + curStatus, statusErr := vmHandler.WaitToGetVMInfo(newVMIID) if statusErr != nil { rtnErr := logAndReturnError(callLogInfo, "Failed to Wait to Get the VM info. : ", statusErr) return irs.VMInfo{}, rtnErr @@ -472,10 +472,9 @@ func (vmHandler *NcpVMHandler) MappingServerInfo(NcpInstance *server.ServerInsta cblogger.Debug(error.Error()) cblogger.Debug("Failed to Get VPC Name from Tag of the VM instance!!") // return irs.VMInfo{}, error // Caution!! - } else { - cblogger.Infof("# vpcName : [%s]", vpcName) - cblogger.Infof("# subnetName : [%s]", subnetName) } + // cblogger.Infof("# vpcName : [%s]", vpcName) + // cblogger.Infof("# subnetName : [%s]", subnetName) if len(vpcName) < 1 { cblogger.Debug("Failed to Get VPC Name from Tag!!") @@ -521,55 +520,20 @@ func (vmHandler *NcpVMHandler) GetVM(vmIID irs.IID) (irs.VMInfo, error) { InitLog() callLogInfo := GetCallLogScheme(vmHandler.RegionInfo.Zone, call.VM, vmIID.NameId, "GetVM()") - instanceNumList := []*string{ncloud.String(vmIID.SystemId)} - // spew.Dump(instanceNumList) - - curStatus, errStatus := vmHandler.GetVMStatus(vmIID) - if errStatus != nil { - rtnErr := logAndReturnError(callLogInfo, "Failed to Get the VM Status : ", errStatus) - return irs.VMInfo{}, rtnErr - } - cblogger.Info("===> VM Status : ", curStatus) - - // Since it's impossible to get VM info. during Creation, ... - switch string(curStatus) { - case "Creating": - cblogger.Infof("Wait for the VM creation before inquiring VM info. The VM status : [%s]", string(curStatus)) - return irs.VMInfo{}, errors.New("The VM status is 'Creating', wait for the VM creation before inquiring VM info. : " + vmIID.SystemId) - default: - cblogger.Infof("===> The VM status not 'Creating', you can get the VM info.") + if strings.EqualFold(vmIID.SystemId, "") { + newErr := fmt.Errorf("Invalid VM System ID!!") + cblogger.Error(newErr.Error()) + return irs.VMInfo{}, newErr } - regionNo, err := vmHandler.GetRegionNo(vmHandler.RegionInfo.Region) - if err != nil { - rtnErr := logAndReturnError(callLogInfo, "Failed to Get NCP Region No :", err) - return irs.VMInfo{}, rtnErr - } - zoneNo, err := vmHandler.GetZoneNo(vmHandler.RegionInfo.Region, vmHandler.RegionInfo.Zone) - if err != nil { - rtnErr := logAndReturnError(callLogInfo, "Failed to Get NCP Zone No of the Zone Code :", err) - return irs.VMInfo{}, rtnErr - } - instanceReq := server.GetServerInstanceListRequest{ - ServerInstanceNoList: instanceNumList, - RegionNo: regionNo, - ZoneNo: zoneNo, - } - callLogStart := call.Start() - result, err := vmHandler.VMClient.V2Api.GetServerInstanceList(&instanceReq) + ncpVMInfo, err := vmHandler.GetNcpVMInfo(vmIID.SystemId) if err != nil { - rtnErr := logAndReturnError(callLogInfo, "Failed to Get VM list from NCP :", err) - return irs.VMInfo{}, rtnErr - } - LoggingInfo(callLogInfo, callLogStart) - - if len(result.ServerInstanceList) < 1 { - newErr := fmt.Errorf("Failed to Find Any VM info with the SystemId : [%s]", vmIID.SystemId) + newErr := fmt.Errorf("Failed to Get the VM Info : [%v]", err) cblogger.Error(newErr.Error()) return irs.VMInfo{}, newErr } - vmInfo, err := vmHandler.MappingServerInfo(result.ServerInstanceList[0]) + vmInfo, err := vmHandler.MappingServerInfo(ncpVMInfo) if err != nil { LoggingError(callLogInfo, err) return irs.VMInfo{}, err @@ -967,9 +931,9 @@ func ConvertVMStatusString(vmStatus string) (irs.VMStatus, error) { resultStatus = "Creating" } else if strings.EqualFold(vmStatus, "booting") { //Caution!! - resultStatus = "Booting" + resultStatus = "Creating" } else if strings.EqualFold(vmStatus, "setting up") { - resultStatus = "Setting_up" + resultStatus = "Creating" } else if strings.EqualFold(vmStatus, "running") { resultStatus = "Running" } else if strings.EqualFold(vmStatus, "shutting down") { @@ -1033,7 +997,7 @@ func (vmHandler *NcpVMHandler) GetVMStatus(vmIID irs.IID) (irs.VMStatus, error) cblogger.Debug(newErr.Error()) // For after Termination!! return irs.VMStatus(""), newErr // Caution!!) Do not fill in "Failed." } - cblogger.Info("Succeeded in Getting ServerInstanceList!!") + // cblogger.Info("Succeeded in Getting ServerInstanceList!!") vmStatus, errStatus := ConvertVMStatusString(*result.ServerInstanceList[0].ServerInstanceStatusName) cblogger.Info("# Converted VM Status : " + vmStatus) @@ -1165,7 +1129,7 @@ func (vmHandler *NcpVMHandler) ListVM() ([]*irs.VMInfo, error) { } // Waiting for up to 300 seconds until VM info. can be get -func (vmHandler *NcpVMHandler) WaitToGetInfo(vmIID irs.IID) (irs.VMStatus, error) { +func (vmHandler *NcpVMHandler) WaitToGetVMInfo(vmIID irs.IID) (irs.VMStatus, error) { cblogger.Info("======> As VM info. cannot be retrieved immediately after VM creation, it waits until running.") curRetryCnt := 0 @@ -1178,14 +1142,13 @@ func (vmHandler *NcpVMHandler) WaitToGetInfo(vmIID irs.IID) (irs.VMStatus, error cblogger.Error(newErr.Error()) return irs.VMStatus("Failed. "), newErr } else { - cblogger.Infof("Succeeded in Getting the VM Status of [%s] : [%s]", vmIID.SystemId, curStatus) + cblogger.Infof("===> VM Status : [%s]", curStatus) } - cblogger.Infof("===> VM Status : [%s]", curStatus) switch string(curStatus) { - case "Creating", "Booting", "Setting_up": + case "Creating": curRetryCnt++ - cblogger.Infof("The VM is still 'Creating' and 'Booting', so wait for a second more before inquiring the VM info.") + cblogger.Infof("The VM Status is still 'Creating', so wait for a second more before inquiring the VM info.") time.Sleep(time.Second * 5) if curRetryCnt > maxRetryCnt { cblogger.Errorf("Despite waiting for a long time(%d sec), the VM status is %s, so it is forcibly finishied.", maxRetryCnt, curStatus) @@ -1193,7 +1156,7 @@ func (vmHandler *NcpVMHandler) WaitToGetInfo(vmIID irs.IID) (irs.VMStatus, error } default: - cblogger.Infof("===> ### The VM Creation is finished, stopping the waiting.") + cblogger.Infof("===> ### The VM Creation has ended, stopping the waiting.") return irs.VMStatus(curStatus), nil //break } @@ -1221,11 +1184,11 @@ func (vmHandler *NcpVMHandler) WaitToDelPublicIp(vmIID irs.IID) (irs.VMStatus, e switch string(curStatus) { case "Suspended", "Terminating": curRetryCnt++ - cblogger.Infof("The VM is still 'Terminating', so wait for a second more before inquiring the VM info.") + cblogger.Infof("The VM Status is still 'Terminating', so wait for a second more before inquiring the VM info.") time.Sleep(time.Second * 5) if curRetryCnt > maxRetryCnt { cblogger.Errorf("Despite waiting for a long time(%d sec), the VM status is '%s', so it is forcibly finished.", maxRetryCnt, curStatus) - return irs.VMStatus("Failed"), errors.New("Despite waiting for a long time, the VM status is 'Creating', so it is forcibly finishied.") + return irs.VMStatus("Failed"), errors.New("Despite waiting for a long time, the VM status is 'Terminating', so it is forcibly finishied.") } default: @@ -1416,28 +1379,14 @@ func (vmHandler *NcpVMHandler) DeleteVMTags(vmID *string) (bool, error) { return true, nil } -func (vmHandler *NcpVMHandler) GetNcpVMInfo(instanceId string) (*server.ServerInstance, error) { +func (vmHandler *NcpVMHandler) GetNcpVMInfo(vmId string) (*server.ServerInstance, error) { cblogger.Info("NCP Classic Cloud driver: called GetNcpVMInfo()") - - vmIID := irs.IID{SystemId: instanceId} - instanceNumList := []*string{ncloud.String(instanceId)} - - curStatus, errStatus := vmHandler.GetVMStatus(vmIID) - if errStatus != nil { - newErr := fmt.Errorf("Failed to Get the Status of the VM : [%v]", errStatus) + + if strings.EqualFold(vmId, "") { + newErr := fmt.Errorf("Invalid VM ID!!") cblogger.Error(newErr.Error()) return nil, newErr } - cblogger.Info("===> VM Status : ", curStatus) - - // Since it's impossible to get VM info. during Creation, ... - switch string(curStatus) { - case "Creating", "Booting": - cblogger.Infof("Wait for the VM creation before inquiring VM info. The VM status : [%s]", string(curStatus)) - return nil, errors.New("The VM status is 'Creating' or 'Booting', wait for the VM creation before inquiring VM info. : " + vmIID.SystemId) - default: - cblogger.Infof("===> The VM status not 'Creating' or 'Booting', you can get the VM info.") - } regionNo, err := vmHandler.GetRegionNo(vmHandler.RegionInfo.Region) if err != nil { @@ -1450,18 +1399,18 @@ func (vmHandler *NcpVMHandler) GetNcpVMInfo(instanceId string) (*server.ServerIn return nil, err } instanceReq := server.GetServerInstanceListRequest{ - ServerInstanceNoList: instanceNumList, + ServerInstanceNoList: []*string{ncloud.String(vmId)}, RegionNo: regionNo, ZoneNo: zoneNo, } result, err := vmHandler.VMClient.V2Api.GetServerInstanceList(&instanceReq) if err != nil { - newErr := fmt.Errorf("Failed to Find VM list with the SystemId from NCP : [%s], [%v]", vmIID.SystemId, err) + newErr := fmt.Errorf("Failed to Find VM list with the SystemId from NCP : [%s], [%v]", vmId, err) cblogger.Error(newErr.Error()) return nil, newErr } if len(result.ServerInstanceList) < 1 { - newErr := fmt.Errorf("Failed to Find Any VM info with the SystemId : [%s]", vmIID.SystemId) + newErr := fmt.Errorf("Failed to Find Any VM info with the SystemId : [%s]", vmId) cblogger.Error(newErr.Error()) return nil, newErr } From b9872fd78012c9acb4b1a35721ffb0d91a8c8faa Mon Sep 17 00:00:00 2001 From: dev4unet Date: Wed, 24 Jul 2024 04:47:44 +0000 Subject: [PATCH 18/32] Added NLB and Cluster related Add / Remove functions --- .../drivers/aws/connect/AwsCloudConnection.go | 4 +- .../drivers/aws/main/Test_Resources.go | 28 +- .../drivers/aws/resources/TagHandler.go | 248 +++++++++++++++++- 3 files changed, 253 insertions(+), 27 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/aws/connect/AwsCloudConnection.go b/cloud-control-manager/cloud-driver/drivers/aws/connect/AwsCloudConnection.go index 424000f90..bf03129a4 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/connect/AwsCloudConnection.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/connect/AwsCloudConnection.go @@ -115,12 +115,12 @@ func (cloudConn *AwsCloudConnection) CreateSecurityHandler() (irs.SecurityHandle } func (cloudConn *AwsCloudConnection) CreateTagHandler() (irs.TagHandler, error) { - handler := ars.AwsTagHandler{Region: cloudConn.Region, Client: cloudConn.VMClient, NLBClient: cloudConn.NLBClient} + handler := ars.AwsTagHandler{Region: cloudConn.Region, Client: cloudConn.VMClient, NLBClient: cloudConn.NLBClient, EKSClient: cloudConn.EKSClient} return &handler, nil } func (cloudConn *AwsCloudConnection) CreateAwsTagHandler() ars.AwsTagHandler { - handler := ars.AwsTagHandler{Region: cloudConn.Region, Client: cloudConn.VMClient, NLBClient: cloudConn.NLBClient} + handler := ars.AwsTagHandler{Region: cloudConn.Region, Client: cloudConn.VMClient, NLBClient: cloudConn.NLBClient, EKSClient: cloudConn.EKSClient} return handler } diff --git a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go index 0e0f8a51a..64837edcc 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go @@ -1449,32 +1449,33 @@ func handleCluster() { } subnets := []irs.IID{} - subnets = append(subnets, irs.IID{SystemId: "subnet-0d30ee6b367974a39"}) //a1 - subnets = append(subnets, irs.IID{SystemId: "subnet-06d5c04b32019b81f"}) //c1 - subnets = append(subnets, irs.IID{SystemId: "subnet-05c5d26bd2f014591"}) //a2 + subnets = append(subnets, irs.IID{SystemId: "subnet-02127b9d8c84f7440"}) //2a + subnets = append(subnets, irs.IID{SystemId: "subnet-0c2b7e03a5f397e25"}) //2c //vpc-0c4d36a3ac3924419 clusterReqInfo := irs.ClusterInfo{ - IId: irs.IID{NameId: "cb-eks-cluster-test01"}, + //TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}, {Key: "Name", Value: securityName+"123"}}, + TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}}, + IId: irs.IID{NameId: "cb-eks-cluster-tag-test", SystemId: "cb-eks-cluster-tag-test"}, //Version : "1.23.3", //K8s version Network: irs.NetworkInfo{ - VpcIID: irs.IID{SystemId: "vpc-0c4d36a3ac3924419"}, + VpcIID: irs.IID{SystemId: "vpc-0a115f43d4fcbab36"}, //SubnetIID: [irs.IID{SystemId: "subnet-262d6d7a"},irs.IID{SystemId: "vpc-c0479cab"}], SubnetIIDs: subnets, }, } // nlbReqInfo reqNodeGroupInfo := irs.NodeGroupInfo{ - IId: irs.IID{NameId: "cb-eks-node-test01"}, + IId: irs.IID{NameId: "cb-eks-node-tag-test"}, MinNodeSize: 1, MaxNodeSize: 2, // VM config. - ImageIID: irs.IID{SystemId: "ami-00e07ff65a55e3ca5"}, // Amazon Linux 2 (AL2_x86_64) - https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html + ImageIID: irs.IID{SystemId: "ami-056a29f2eddc40520"}, // Amazon Linux 2 (AL2_x86_64) - https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html VMSpecName: "t3.medium", RootDiskType: "SSD(gp2)", // "SSD(gp2)", "Premium SSD", ... RootDiskSize: "20", // "", "default", "50", "1000" (GB) - KeyPairIID: irs.IID{SystemId: "japan-test"}, + KeyPairIID: irs.IID{SystemId: "CB-KeyPairTagTest"}, //Status NodeGroupStatus @@ -1512,7 +1513,7 @@ func handleCluster() { case 1: result, err := handler.ListCluster() if err != nil { - cblogger.Infof(" Cluster List Lookup Failed : ", err) + cblogger.Info(" Cluster List Lookup Failed : ", err) } else { cblogger.Info("Cluster List Lookup Result") cblogger.Debug(result) @@ -1532,7 +1533,7 @@ func handleCluster() { if err != nil { cblogger.Infof(clusterReqInfo.IId.NameId, " Cluster Create Fail : ", err) } else { - cblogger.Infof("Cluster Create Success : ", result) + cblogger.Info("Cluster Create Success : ", result) clusterReqInfo.IId = result.IId // 조회 및 삭제를 위해 생성된 ID로 변경 if cblogger.Level.String() == "debug" { spew.Dump(result) @@ -2076,7 +2077,8 @@ func readConfigFile() Config { } func main() { - handleTag() + // myimage / disk + //handleTag() // handlePublicIP() // PublicIP 생성 후 conf //handleKeyPair() @@ -2086,9 +2088,9 @@ func main() { // handleImage() //AMI // handleVNic() //Lancard // handleVMSpec() - handleNLB() + //handleNLB() handleCluster() //handleRegionZone() //handlePriceInfo() - handleTag() + //handleTag() } diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go index 76cdc47c2..5c9151887 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go @@ -24,6 +24,7 @@ import ( //"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/aws/aws-sdk-go/service/eks" "github.com/aws/aws-sdk-go/service/elbv2" call "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/call-log" @@ -35,6 +36,7 @@ type AwsTagHandler struct { Region idrv.RegionInfo Client *ec2.EC2 NLBClient *elbv2.ELBV2 + EKSClient *eks.EKS } // Map of RSType to AWS resource types @@ -76,6 +78,20 @@ func (tagHandler *AwsTagHandler) AddTag(resType irs.RSType, resIID irs.IID, tag return irs.KeyValue{}, errors.New(msg) } + if resType == irs.NLB || resType == irs.CLUSTER { + var err error + if resType == irs.NLB { + err = tagHandler.AddNLBTag(resIID, tag) + } else if resType == irs.CLUSTER { + err = tagHandler.AddClusterTag(resIID, tag) + } + + if err != nil { + return irs.KeyValue{}, err + } + return tagHandler.GetTag(resType, resIID, tag.Key) + } + resIID = tagHandler.GetRealResourceId(resType, resIID) // fix some resource id error hiscallInfo := GetCallLogScheme(tagHandler.Region, call.TAG, resIID.SystemId, "CreateTags()") @@ -106,6 +122,41 @@ func (tagHandler *AwsTagHandler) AddTag(resType irs.RSType, resIID irs.IID, tag return tag, nil } +func (tagHandler *AwsTagHandler) AddNLBTag(resIID irs.IID, tag irs.KeyValue) error { + input := &elbv2.AddTagsInput{ + ResourceArns: []*string{aws.String(resIID.SystemId)}, + Tags: []*elbv2.Tag{ + { + Key: aws.String(tag.Key), + Value: aws.String(tag.Value), + }, + }, + } + + _, err := tagHandler.NLBClient.AddTags(input) + if err != nil { + return fmt.Errorf("failed to add tag to NLB: %w", err) + } + + return nil +} + +func (tagHandler *AwsTagHandler) AddClusterTag(resIID irs.IID, tag irs.KeyValue) error { + input := &eks.TagResourceInput{ + ResourceArn: aws.String(resIID.SystemId), + Tags: map[string]*string{ + tag.Key: aws.String(tag.Value), + }, + } + + _, err := tagHandler.EKSClient.TagResource(input) + if err != nil { + return fmt.Errorf("failed to add tag to EKS cluster: %w", err) + } + + return nil +} + func (tagHandler *AwsTagHandler) GetAllNLBTags() ([]*irs.TagInfo, error) { // Step 1: List all load balancers and store their ARNs and Names lbArnToName := make(map[string]string) @@ -157,7 +208,87 @@ func (tagHandler *AwsTagHandler) GetAllNLBTags() ([]*irs.TagInfo, error) { return allTagInfos, nil } -func (tagHandler *AwsTagHandler) GetNLBTags(resIID irs.IID) ([]irs.KeyValue, error) { +// GetAllClusterTags retrieves tags for all EKS clusters. +func (tagHandler *AwsTagHandler) GetAllClusterTags() ([]*irs.TagInfo, error) { + var allTagInfos []*irs.TagInfo + + err := tagHandler.EKSClient.ListClustersPages(&eks.ListClustersInput{}, func(page *eks.ListClustersOutput, lastPage bool) bool { + for _, clusterName := range page.Clusters { + resIID := irs.IID{ + NameId: *clusterName, + SystemId: *clusterName, + } + + tagInfos, err := tagHandler.GetClusterTags(resIID) + if err != nil { + cblogger.Errorf("failed to get tags for EKS cluster %s: %v", *clusterName, err) + continue + } + + // Process only if Tag exists + if len(tagInfos) == 0 { + continue + } + + tagInfo := &irs.TagInfo{ + ResType: irs.CLUSTER, + ResIId: resIID, + TagList: tagInfos, + } + + allTagInfos = append(allTagInfos, tagInfo) + } + return !lastPage + }) + + if err != nil { + return nil, fmt.Errorf("failed to list EKS clusters: %w", err) + } + + if len(allTagInfos) == 0 { + return nil, fmt.Errorf("no EKS clusters found") + } + + return allTagInfos, nil +} + +func (tagHandler *AwsTagHandler) GetClusterTags(resIID irs.IID, key ...string) ([]irs.KeyValue, error) { + cblogger.Debugf("Req resIID:[%s]", resIID) + input := &eks.DescribeClusterInput{ + Name: aws.String(resIID.SystemId), + } + + result, err := tagHandler.EKSClient.DescribeCluster(input) + if err != nil { + return nil, fmt.Errorf("failed to describe EKS cluster: %w", err) + } + + if cblogger.Level.String() == "debug" { + cblogger.Debug(result) + } + + var retTagList []irs.KeyValue + if len(key) > 0 { // If the key value exists + specificKey := key[0] + if value, exists := result.Cluster.Tags[specificKey]; exists { + retTagList = append(retTagList, irs.KeyValue{ + Key: specificKey, + Value: *value, + }) + } + } else { // If the key value not exists + for k, v := range result.Cluster.Tags { + retTagList = append(retTagList, irs.KeyValue{ + Key: k, + Value: *v, + }) + } + } + + return retTagList, nil +} + +func (tagHandler *AwsTagHandler) GetNLBTags(resIID irs.IID, key ...string) ([]irs.KeyValue, error) { input := &elbv2.DescribeTagsInput{ ResourceArns: []*string{ aws.String(resIID.SystemId), @@ -173,16 +304,27 @@ func (tagHandler *AwsTagHandler) GetNLBTags(resIID irs.IID) ([]irs.KeyValue, err return nil, fmt.Errorf("no tags found for load balancer: %s", resIID.SystemId) } - if cblogger.Level.String() == "debug" { - cblogger.Debug(result) - } + cblogger.Debug(result) var retTagList []irs.KeyValue - for _, tag := range result.TagDescriptions[0].Tags { - retTagList = append(retTagList, irs.KeyValue{ - Key: aws.StringValue(tag.Key), - Value: aws.StringValue(tag.Value), - }) + if len(key) > 0 { // If the key value exists + specificKey := key[0] + for _, tag := range result.TagDescriptions[0].Tags { + if aws.StringValue(tag.Key) == specificKey { + retTagList = append(retTagList, irs.KeyValue{ + Key: aws.StringValue(tag.Key), + Value: aws.StringValue(tag.Value), + }) + break + } + } + } else { // If the key value not exists + for _, tag := range result.TagDescriptions[0].Tags { + retTagList = append(retTagList, irs.KeyValue{ + Key: aws.StringValue(tag.Key), + Value: aws.StringValue(tag.Value), + }) + } } return retTagList, nil @@ -199,6 +341,8 @@ func (tagHandler *AwsTagHandler) ListTag(resType irs.RSType, resIID irs.IID) ([] if resType == irs.NLB { return tagHandler.GetNLBTags(resIID) + } else if resType == irs.CLUSTER { + return tagHandler.GetClusterTags(resIID) } resIID = tagHandler.GetRealResourceId(resType, resIID) // fix some resource id error @@ -252,6 +396,29 @@ func (tagHandler *AwsTagHandler) GetTag(resType irs.RSType, resIID irs.IID, key cblogger.Error(msg) return irs.KeyValue{}, errors.New(msg) } + + // NLB and Cluster use different APIs + if resType == irs.NLB || resType == irs.CLUSTER { + var tagList []irs.KeyValue + var err error + + if resType == irs.NLB { + tagList, err = tagHandler.GetNLBTags(resIID, key) + } else if resType == irs.CLUSTER { + tagList, err = tagHandler.GetClusterTags(resIID, key) + } + + if err != nil { + return irs.KeyValue{}, fmt.Errorf("failed to get tags: %w", err) + } + + if len(tagList) == 0 { + return irs.KeyValue{}, nil + } else { + return tagList[0], nil + } + } + resIID = tagHandler.GetRealResourceId(resType, resIID) // fix some resource id error input := &ec2.DescribeTagsInput{ @@ -353,6 +520,13 @@ func (tagHandler *AwsTagHandler) RemoveTag(resType irs.RSType, resIID irs.IID, k cblogger.Error(msg) return false, errors.New(msg) } + + if resType == irs.NLB { + return tagHandler.RemoveNLBTag(resIID, key) + } else if resType == irs.CLUSTER { + return tagHandler.RemoveClusterTag(resIID, key) + } + resIID = tagHandler.GetRealResourceId(resType, resIID) // fix some resource id error input := &ec2.DeleteTagsInput{ @@ -389,6 +563,38 @@ func (tagHandler *AwsTagHandler) RemoveTag(resType irs.RSType, resIID irs.IID, k return true, nil } +func (tagHandler *AwsTagHandler) RemoveNLBTag(resIID irs.IID, tagKey string) (bool, error) { + input := &elbv2.RemoveTagsInput{ + ResourceArns: []*string{aws.String(resIID.SystemId)}, + TagKeys: []*string{ + aws.String(tagKey), + }, + } + + _, err := tagHandler.NLBClient.RemoveTags(input) + if err != nil { + return false, fmt.Errorf("failed to remove tag from NLB: %w", err) + } + + return true, nil +} + +func (tagHandler *AwsTagHandler) RemoveClusterTag(resIID irs.IID, tagKey string) (bool, error) { + input := &eks.UntagResourceInput{ + ResourceArn: aws.String(resIID.SystemId), + TagKeys: []*string{ + aws.String(tagKey), + }, + } + + _, err := tagHandler.EKSClient.UntagResource(input) + if err != nil { + return false, fmt.Errorf("failed to remove tag from EKS cluster: %w", err) + } + + return true, nil +} + // Extracts a list of Key or Value tags corresponding to keyword from the tagInfos array. func (tagHandler *AwsTagHandler) ExtractTagKeyValue(tagInfos []*irs.TagInfo, keyword string) []*irs.TagInfo { var matchingTagInfos []*irs.TagInfo @@ -398,6 +604,7 @@ func (tagHandler *AwsTagHandler) ExtractTagKeyValue(tagInfos []*irs.TagInfo, key } /* + // All tags for _, tagInfo := range tagInfos { for _, kv := range tagInfo.TagList { if kv.Key == keyword || kv.Value == keyword { @@ -452,6 +659,15 @@ func (tagHandler *AwsTagHandler) FindTag(resType irs.RSType, keyword string) ([] //spew.Dump(nlbTaginfos) return tagHandler.ExtractTagKeyValue(nlbTaginfos, keyword), nil } + } else if resType == irs.CLUSTER { + // Add a list of k8s Tags if this is a all search + if keyword == "" || keyword == "*" { + return tagHandler.GetAllClusterTags() + } else { + k8sTaginfos, _ := tagHandler.GetAllClusterTags() + //spew.Dump(k8sTaginfos) + return tagHandler.ExtractTagKeyValue(k8sTaginfos, keyword), nil + } } if awsResType, ok := rsTypeToAwsResourceTypeMap[resType]; ok { @@ -472,9 +688,9 @@ func (tagHandler *AwsTagHandler) FindTag(resType irs.RSType, keyword string) ([] processTags := func(result *ec2.DescribeTagsOutput) { if cblogger.Level.String() == "debug" { //cblogger.Debug(result) - cblogger.Debug("=================================") - spew.Dump(result) - cblogger.Debug("=================================") + //cblogger.Debug("=================================") + //spew.Dump(result) + //cblogger.Debug("=================================") } for _, tag := range result.Tags { @@ -578,11 +794,19 @@ func (tagHandler *AwsTagHandler) FindTag(resType irs.RSType, keyword string) ([] // Add a list of NLB Tags if this is a all search if resType == irs.ALL { + //nlb nlbTaginfos, _ := tagHandler.GetAllNLBTags() if keyword != "" && keyword != "*" { nlbTaginfos = tagHandler.ExtractTagKeyValue(nlbTaginfos, keyword) } tagInfos = append(tagInfos, nlbTaginfos...) + + //cluster + k8sTaginfos, _ := tagHandler.GetAllClusterTags() + if keyword != "" && keyword != "*" { + k8sTaginfos = tagHandler.ExtractTagKeyValue(k8sTaginfos, keyword) + } + tagInfos = append(tagInfos, k8sTaginfos...) } return tagInfos, nil From 26cf6c4148f8eed341936fa91a78a33c7858d21d Mon Sep 17 00:00:00 2001 From: innodreamer Date: Wed, 24 Jul 2024 15:41:03 +0900 Subject: [PATCH 19/32] Unify NCP VPC VM Creating Status (Booting / Setting up -> Creating) --- .../drivers/ncp/resources/VMHandler.go | 16 +---- .../drivers/ncpvpc/resources/VMHandler.go | 71 ++++--------------- 2 files changed, 15 insertions(+), 72 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/ncp/resources/VMHandler.go b/cloud-control-manager/cloud-driver/drivers/ncp/resources/VMHandler.go index 24d716035..6fe71dade 100644 --- a/cloud-control-manager/cloud-driver/drivers/ncp/resources/VMHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ncp/resources/VMHandler.go @@ -62,7 +62,6 @@ func init() { func (vmHandler *NcpVMHandler) StartVM(vmReqInfo irs.VMReqInfo) (irs.VMInfo, error) { cblogger.Info("NCP Classic Cloud driver: called StartVM()!!") - InitLog() callLogInfo := GetCallLogScheme(vmHandler.RegionInfo.Zone, call.VM, vmReqInfo.IId.NameId, "StartVM()") @@ -481,7 +480,6 @@ func (vmHandler *NcpVMHandler) MappingServerInfo(NcpInstance *server.ServerInsta } else { // To get the VPC info. vpcHandler := NcpVPCHandler { - CredentialInfo: vmHandler.CredentialInfo, RegionInfo: vmHandler.RegionInfo, VMClient: vmHandler.VMClient, } @@ -502,7 +500,7 @@ func (vmHandler *NcpVMHandler) MappingServerInfo(NcpInstance *server.ServerInsta } } } - cblogger.Infof("NCP Instance Uptime : [%s]", *NcpInstance.Uptime) + // cblogger.Infof("NCP Instance Uptime : [%s]", *NcpInstance.Uptime) // Note : NCP VPC PlatformType : LNX32, LNX64, WND32, WND64, UBD64, UBS64 if strings.Contains(*NcpInstance.PlatformType.Code, "LNX") || strings.Contains(*NcpInstance.PlatformType.Code, "UB") { @@ -543,8 +541,6 @@ func (vmHandler *NcpVMHandler) GetVM(vmIID irs.IID) (irs.VMInfo, error) { func (vmHandler *NcpVMHandler) SuspendVM(vmIID irs.IID) (irs.VMStatus, error) { cblogger.Info("NCP Classic Cloud driver: called SuspendVM()!!") - cblogger.Infof("vmID : [%s]", vmIID.SystemId) - InitLog() callLogInfo := GetCallLogScheme(vmHandler.RegionInfo.Zone, call.VM, vmIID.NameId, "SuspendVM()") @@ -605,8 +601,6 @@ func (vmHandler *NcpVMHandler) SuspendVM(vmIID irs.IID) (irs.VMStatus, error) { func (vmHandler *NcpVMHandler) ResumeVM(vmIID irs.IID) (irs.VMStatus, error) { cblogger.Info("NCP Classic Cloud driver: called ResumeVM()!") - cblogger.Infof("vmID : " + vmIID.SystemId) - InitLog() callLogInfo := GetCallLogScheme(vmHandler.RegionInfo.Zone, call.VM, vmIID.NameId, "ResumeVM()") @@ -673,8 +667,6 @@ func (vmHandler *NcpVMHandler) ResumeVM(vmIID irs.IID) (irs.VMStatus, error) { func (vmHandler *NcpVMHandler) RebootVM(vmIID irs.IID) (irs.VMStatus, error) { cblogger.Info("NCP Classic Cloud driver: called RebootVM()!") - cblogger.Infof("vmID : [%s]", vmIID.SystemId) - InitLog() callLogInfo := GetCallLogScheme(vmHandler.RegionInfo.Zone, call.VM, vmIID.NameId, "RebootVM()") @@ -742,8 +734,6 @@ func (vmHandler *NcpVMHandler) RebootVM(vmIID irs.IID) (irs.VMStatus, error) { func (vmHandler *NcpVMHandler) TerminateVM(vmIID irs.IID) (irs.VMStatus, error) { cblogger.Info("NCP Classic Cloud driver: called TerminateVM()!") - cblogger.Infof("vmID : [%s]", vmIID.SystemId) - InitLog() callLogInfo := GetCallLogScheme(vmHandler.RegionInfo.Zone, call.VM, vmIID.NameId, "TerminateVM()") @@ -961,7 +951,6 @@ func ConvertVMStatusString(vmStatus string) (irs.VMStatus, error) { func (vmHandler *NcpVMHandler) GetVMStatus(vmIID irs.IID) (irs.VMStatus, error) { cblogger.Info("NCP Classic Cloud driver: called GetVMStatus()!") - InitLog() callLogInfo := GetCallLogScheme(vmHandler.RegionInfo.Zone, call.VM, vmIID.NameId, "GetVMStatus()") @@ -1000,13 +989,12 @@ func (vmHandler *NcpVMHandler) GetVMStatus(vmIID irs.IID) (irs.VMStatus, error) // cblogger.Info("Succeeded in Getting ServerInstanceList!!") vmStatus, errStatus := ConvertVMStatusString(*result.ServerInstanceList[0].ServerInstanceStatusName) - cblogger.Info("# Converted VM Status : " + vmStatus) + // cblogger.Info("# Converted VM Status : " + vmStatus) return vmStatus, errStatus } func (vmHandler *NcpVMHandler) ListVMStatus() ([]*irs.VMStatusInfo, error) { cblogger.Info("NCP Classic Cloud driver: called ListVMStatus()!") - InitLog() callLogInfo := GetCallLogScheme(vmHandler.RegionInfo.Zone, call.VM, "ListVMStatus()", "ListVMStatus()") diff --git a/cloud-control-manager/cloud-driver/drivers/ncpvpc/resources/VMHandler.go b/cloud-control-manager/cloud-driver/drivers/ncpvpc/resources/VMHandler.go index e5d0d6e8c..20c64a9ba 100644 --- a/cloud-control-manager/cloud-driver/drivers/ncpvpc/resources/VMHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ncpvpc/resources/VMHandler.go @@ -323,63 +323,19 @@ func (vmHandler *NcpVpcVMHandler) GetVM(vmIID irs.IID) (irs.VMInfo, error) { return irs.VMInfo{}, newErr } - curStatus, statusErr := vmHandler.GetVMStatus(vmIID) - if statusErr != nil { - newErr := fmt.Errorf("Failed to Get the VM Status with the VM ID : [%s], [%v]", vmIID.SystemId, statusErr) - cblogger.Error(newErr.Error()) - LoggingError(callLogInfo, newErr) - return irs.VMInfo{}, newErr - } - cblogger.Infof("===> VM Status : [%s]", curStatus) - - // Since it's impossible to get VM info. during Creation, ... - switch string(curStatus) { - case "Creating": - cblogger.Infof("The VM status is '%s', so wait for the VM creation before inquiring the info.", string(curStatus)) - return irs.VMInfo{}, errors.New("The VM status is 'Creating', so wait for the VM creation before inquiring the info. : " + vmIID.SystemId) - default: - cblogger.Infof("===> The VM status is not 'Creating', you can get the VM info.") - } - - /* - newVMIID := irs.IID{SystemId: systemId} - - curStatus, statusErr := vmHandler.WaitToGetInfo(newVMIID) - if statusErr != nil { - cblogger.Error(statusErr.Error()) - return irs.VMInfo{}, nil - } - */ - instanceNumList := []*string{ncloud.String(vmIID.SystemId),} - instanceReq := vserver.GetServerInstanceListRequest{ - RegionCode: ncloud.String(vmHandler.RegionInfo.Region), // $$$ Caution!! - ServerInstanceNoList: instanceNumList, - } - start := call.Start() - result, err := vmHandler.VMClient.V2Api.GetServerInstanceList(&instanceReq) + ncpVMInfo, err := vmHandler.GetNcpVMInfo(vmIID.SystemId) if err != nil { - newErr := fmt.Errorf("Failed to Find VM Instance List from NCP VPC!! : [%v]", err) + newErr := fmt.Errorf("Failed to Get the VM Info : [%v]", err) cblogger.Error(newErr.Error()) - LoggingError(callLogInfo, newErr) return irs.VMInfo{}, newErr } - LoggingInfo(callLogInfo, start) - if len(result.ServerInstanceList) < 1 { - newErr := fmt.Errorf("Failed to Find the VM Info. The VM does Not Exist!!") - cblogger.Error(newErr.Error()) - LoggingError(callLogInfo, newErr) - return irs.VMInfo{}, newErr - } - - vmInfo, err := vmHandler.MappingServerInfo(result.ServerInstanceList[0]) + vmInfo, err := vmHandler.MappingServerInfo(ncpVMInfo) if err != nil { - newErr := fmt.Errorf("Failed to Map the VM Info!! : [%v]", err) - cblogger.Error(newErr.Error()) - LoggingError(callLogInfo, newErr) - return irs.VMInfo{}, newErr + LoggingError(callLogInfo, err) + return irs.VMInfo{}, err } - return vmInfo, nil + return vmInfo, nil } func (vmHandler *NcpVpcVMHandler) SuspendVM(vmIID irs.IID) (irs.VMStatus, error) { @@ -774,9 +730,9 @@ func ConvertVMStatusString(vmStatus string) (irs.VMStatus, error) { resultStatus = "Creating" } else if strings.EqualFold(vmStatus, "booting") { //Caution!! - resultStatus = "Booting" + resultStatus = "Creating" } else if strings.EqualFold(vmStatus, "setting up") { - resultStatus = "Setting_up" + resultStatus = "Creating" } else if strings.EqualFold(vmStatus, "running") { resultStatus = "Running" } else if strings.EqualFold(vmStatus, "shutting down") { @@ -838,7 +794,7 @@ func (vmHandler *NcpVpcVMHandler) GetVMStatus(vmIID irs.IID) (irs.VMStatus, erro } vmStatus, statusErr := ConvertVMStatusString(*result.ServerInstanceList[0].ServerInstanceStatusName) - cblogger.Infof("VM Status of [%s] : [%s]", vmIID.SystemId, vmStatus) + // cblogger.Infof("VM Status of [%s] : [%s]", vmIID.SystemId, vmStatus) return vmStatus, statusErr } @@ -1338,14 +1294,13 @@ func (vmHandler *NcpVpcVMHandler) WaitToGetInfo(vmIID irs.IID) (irs.VMStatus, er cblogger.Errorf("Failed to Get the VM Status of [%s]", vmIID.SystemId) cblogger.Error(statusErr.Error()) } else { - cblogger.Infof("Succeeded in Getting the Status of VM [%s] : [%s]", vmIID.SystemId, curStatus) + cblogger.Infof("===> VM Status : [%s]", curStatus) } - cblogger.Infof("===> VM Status : [%s]", curStatus) switch string(curStatus) { - case "Creating", "Booting", "Setting_up": + case "Creating": curRetryCnt++ - cblogger.Infof("The VM is 'Creating' and 'Booting', so wait for a second more before inquiring the VM info.") + cblogger.Infof("The VM is 'Creating', so wait for a second more before inquiring the VM info.") time.Sleep(time.Second * 5) if curRetryCnt > maxRetryCnt { cblogger.Errorf("Despite waiting for a long time(%d sec), the VM status is '%s', so it is forcibly finishied.", maxRetryCnt, curStatus) @@ -1375,7 +1330,7 @@ func (vmHandler *NcpVpcVMHandler) WaitToDelPublicIp(vmIID irs.IID) (irs.VMStatus } else { cblogger.Infof("Succeeded in Getting the VM Status of [%s]", vmIID.SystemId) } - cblogger.Infof("===> VM Status [%s] : ", curStatus) + cblogger.Infof("===> VM Status : [%s]", curStatus) switch string(curStatus) { case "Suspended", "Terminating": From a5bfb03ac22232c2d1259ae617892614ee25b7be Mon Sep 17 00:00:00 2001 From: dev4unet Date: Thu, 25 Jul 2024 08:07:44 +0000 Subject: [PATCH 20/32] Tested the Tag feature in Disk / MyImage --- .../drivers/aws/main/Test_Resources.go | 194 +++++++++++++++++- .../drivers/aws/resources/TagHandler.go | 33 ++- 2 files changed, 216 insertions(+), 11 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go index 64837edcc..d38de34fe 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go @@ -1806,12 +1806,15 @@ func handleTag() { var reqType irs.RSType = irs.KEY //reqIID := irs.IID{SystemId: "i-02ac1c4ff1d40815c"} reqIID := irs.IID{SystemId: "CB-KeyPairTest123123"} + reqIID = irs.IID{SystemId: "ami-03cda261fe3252863"} reqTag := irs.KeyValue{Key: "tag3", Value: "tag3 test"} reqKey := "tag3" reqKey = "CB-KeyPairTagTest" reqKey = "cb-nlb-test01123" - reqKey = "" + reqKey = "Name2" + reqKey = "cb-eks-cluster-tag-test" + reqKey = "tag3" reqType = irs.ALL for { @@ -1901,11 +1904,184 @@ func handleTag() { } } +// Test Disk +func handleDisk() { + cblogger.Debug("Start Disk Resource Test") + + ResourceHandler, err := getResourceHandler("Disk") + if err != nil { + panic(err) + } + handler := ResourceHandler.(irs.DiskHandler) + + reqIID := irs.IID{NameId: "tag-test", SystemId: "vol-0d0bdcd08f027c2a1"} + reqKey := "tag3" + reqInfo := irs.DiskInfo{ + IId: reqIID, + DiskType: "gp2", + DiskSize: "50", + + //TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}, {Key: "Name", Value: securityName+"123"}}, + TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}}, + } + + for { + fmt.Println("TagHandler Management") + fmt.Println("0. Quit") + fmt.Println("1. Disk List") + fmt.Println("2. Disk Create") + fmt.Println("3. Disk Get") + fmt.Println("4. Disk Delete") + + var commandNum int + inputCnt, err := fmt.Scan(&commandNum) + if err != nil { + panic(err) + } + + if inputCnt == 1 { + switch commandNum { + case 0: + return + + case 1: + cblogger.Infof("Lookup disk list") + result, err := handler.ListDisk() + if err != nil { + cblogger.Info(" Disk List Lookup Failed : ", err) + } else { + cblogger.Info("Disk List Lookup Result") + cblogger.Debug(result) + cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) + //spew.Dump(result) + cblogger.Info("Number of output results : ", len(result)) + } + + case 2: + cblogger.Infof("[%s] Disk Create Test", reqIID.SystemId) + result, err := handler.CreateDisk(reqInfo) + if err != nil { + cblogger.Infof(reqIID.SystemId, " Disk Create Failed : ", err) + } else { + cblogger.Info("Disk Create Result : ", result) + spew.Dump(result) + } + + case 3: + cblogger.Infof("[%s] Disk Lookup Test - Key[%s]", reqIID.SystemId, reqKey) + result, err := handler.GetDisk(reqIID) + if err != nil { + cblogger.Infof("[%s] Disk Lookup Failed : [%v]", reqKey, err) + } else { + cblogger.Infof("[%s] Disk Lookup Result : [%s]", reqKey, result) + spew.Dump(result) + } + + case 4: + cblogger.Infof("[%s] Disk Delete Test - Key[%s]", reqIID.SystemId, reqKey) + result, err := handler.DeleteDisk(reqIID) + if err != nil { + cblogger.Infof("[%s] Disk Delete Failed : [%v]", reqKey, err) + } else { + cblogger.Infof("[%s] Disk Delete Result : [%v]", reqKey, result) + } + } + } + } +} + +// Test MyImage +func handleMyImage() { + cblogger.Debug("Start MyImage Resource Test") + + ResourceHandler, err := getResourceHandler("MyImage") + if err != nil { + panic(err) + } + handler := ResourceHandler.(irs.MyImageHandler) + + reqIID := irs.IID{NameId: "tag-test", SystemId: "ami-03cda261fe3252863"} + reqKey := "tag3" + reqInfo := irs.MyImageInfo{ + IId: reqIID, + SourceVM: irs.IID{SystemId: "i-0c65033e158e0fd99"}, + + //TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}, {Key: "Name", Value: securityName+"123"}}, + TagList: []irs.KeyValue{{Key: "Name1", Value: "Tag Name Value1"}, {Key: "Name2", Value: "Tag Name Value2"}}, + } + + for { + fmt.Println("TagHandler Management") + fmt.Println("0. Quit") + fmt.Println("1. MyImage List") + fmt.Println("2. MyImage Create") + fmt.Println("3. MyImage Get") + fmt.Println("4. MyImage Delete") + + var commandNum int + inputCnt, err := fmt.Scan(&commandNum) + if err != nil { + panic(err) + } + + if inputCnt == 1 { + switch commandNum { + case 0: + return + + case 1: + cblogger.Infof("Lookup MyImage list") + result, err := handler.ListMyImage() + if err != nil { + cblogger.Info(" MyImage List Lookup Failed : ", err) + } else { + cblogger.Info("MyImage List Lookup Result") + cblogger.Debug(result) + cblogger.Infof("Log Level : [%s]", cblog.GetLevel()) + //spew.Dump(result) + cblogger.Info("Number of output results : ", len(result)) + } + + case 2: + cblogger.Infof("[%s] MyImage Create Test", reqIID.NameId) + result, err := handler.SnapshotVM(reqInfo) + if err != nil { + cblogger.Infof(reqIID.NameId, " MyImage Create Failed : ", err) + } else { + cblogger.Info("MyImage Create Result : ", result) + reqIID = result.IId + spew.Dump(result) + } + + case 3: + cblogger.Infof("[%s] MyImage Lookup Test - Key[%s]", reqIID.SystemId, reqKey) + result, err := handler.GetMyImage(reqIID) + if err != nil { + cblogger.Infof("[%s] MyImage Lookup Failed : [%v]", reqKey, err) + } else { + cblogger.Infof("[%s] MyImage Lookup Result : [%s]", reqKey, result) + spew.Dump(result) + } + + case 4: + cblogger.Infof("[%s] MyImage Delete Test - Key[%s]", reqIID.SystemId, reqKey) + result, err := handler.DeleteMyImage(reqIID) + if err != nil { + cblogger.Infof("[%s] MyImage Delete Failed : [%v]", reqKey, err) + } else { + cblogger.Infof("[%s] MyImage Delete Result : [%v]", reqKey, result) + } + } + } + } +} + // handlerType : resources폴더의 xxxHandler.go에서 Handler이전까지의 문자열 // (예) ImageHandler.go -> "Image" func getResourceHandler(handlerType string) (interface{}, error) { - var cloudDriver idrv.CloudDriver - cloudDriver = new(awsdrv.AwsDriver) + //var cloudDriver idrv.CloudDriver + //cloudDriver = new(awsdrv.AwsDriver) + cloudDriver := new(awsdrv.AwsDriver) config := readConfigFile() connectionInfo := idrv.ConnectionInfo{ @@ -1952,6 +2128,10 @@ func getResourceHandler(handlerType string) (interface{}, error) { resourceHandler, err = cloudConnection.CreatePriceInfoHandler() case "Tag": resourceHandler, err = cloudConnection.CreateTagHandler() + case "Disk": + resourceHandler, err = cloudConnection.CreateDiskHandler() + case "MyImage": + resourceHandler, err = cloudConnection.CreateMyImageHandler() } if err != nil { @@ -2077,9 +2257,11 @@ func readConfigFile() Config { } func main() { - // myimage / disk + handleMyImage() + // myimage //handleTag() // handlePublicIP() // PublicIP 생성 후 conf + // handleDisk() //handleKeyPair() //handleVPC() @@ -2089,8 +2271,8 @@ func main() { // handleVNic() //Lancard // handleVMSpec() //handleNLB() - handleCluster() + //handleCluster() //handleRegionZone() //handlePriceInfo() - //handleTag() + handleTag() } diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go index 5c9151887..28b1beb85 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/TagHandler.go @@ -141,15 +141,33 @@ func (tagHandler *AwsTagHandler) AddNLBTag(resIID irs.IID, tag irs.KeyValue) err return nil } +func (tagHandler *AwsTagHandler) getClusterArn(clusterName string) (string, error) { + input := &eks.DescribeClusterInput{ + Name: aws.String(clusterName), + } + + result, err := tagHandler.EKSClient.DescribeCluster(input) + if err != nil { + return "", fmt.Errorf("failed to describe EKS cluster: %w", err) + } + + return aws.StringValue(result.Cluster.Arn), nil +} + func (tagHandler *AwsTagHandler) AddClusterTag(resIID irs.IID, tag irs.KeyValue) error { + clusterArn, err := tagHandler.getClusterArn(resIID.SystemId) + if err != nil { + return err + } + input := &eks.TagResourceInput{ - ResourceArn: aws.String(resIID.SystemId), + ResourceArn: aws.String(clusterArn), Tags: map[string]*string{ tag.Key: aws.String(tag.Value), }, } - _, err := tagHandler.EKSClient.TagResource(input) + _, err = tagHandler.EKSClient.TagResource(input) if err != nil { return fmt.Errorf("failed to add tag to EKS cluster: %w", err) } @@ -413,7 +431,7 @@ func (tagHandler *AwsTagHandler) GetTag(resType irs.RSType, resIID irs.IID, key } if len(tagList) == 0 { - return irs.KeyValue{}, nil + return irs.KeyValue{}, fmt.Errorf("%s tag key does not exist", key) } else { return tagList[0], nil } @@ -580,14 +598,19 @@ func (tagHandler *AwsTagHandler) RemoveNLBTag(resIID irs.IID, tagKey string) (bo } func (tagHandler *AwsTagHandler) RemoveClusterTag(resIID irs.IID, tagKey string) (bool, error) { + clusterArn, err := tagHandler.getClusterArn(resIID.SystemId) + if err != nil { + return false, err + } + input := &eks.UntagResourceInput{ - ResourceArn: aws.String(resIID.SystemId), + ResourceArn: aws.String(clusterArn), TagKeys: []*string{ aws.String(tagKey), }, } - _, err := tagHandler.EKSClient.UntagResource(input) + _, err = tagHandler.EKSClient.UntagResource(input) if err != nil { return false, fmt.Errorf("failed to remove tag from EKS cluster: %w", err) } From 640d95333e5c61bcbfe662625d818de06bf4bc71 Mon Sep 17 00:00:00 2001 From: handj622 Date: Thu, 25 Jul 2024 20:36:04 +0900 Subject: [PATCH 21/32] IBM: Implement TagHandler --- .../drivers/ibmcloud-vpc/IBMCloudDriver.go | 4 +- .../connect/Ibm_CloudConnection.go | 9 +- .../ibmcloud-vpc/main/Test_Resources.go | 130 ++++- .../ibmcloud-vpc/resources/TagHandler.go | 487 ++++++++++++++++++ 4 files changed, 623 insertions(+), 7 deletions(-) create mode 100644 cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/TagHandler.go diff --git a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/IBMCloudDriver.go b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/IBMCloudDriver.go index 32362e35a..391797c48 100644 --- a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/IBMCloudDriver.go +++ b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/IBMCloudDriver.go @@ -3,6 +3,8 @@ package ibmcloudvpc import ( "context" "errors" + "time" + "github.com/IBM/go-sdk-core/v5/core" "github.com/IBM/platform-services-go-sdk/globaltaggingv1" vpc0230 "github.com/IBM/vpc-go-sdk/0.23.0/vpcv1" @@ -12,7 +14,6 @@ import ( "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/utils/kubernetesserviceapiv1" idrv "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces" icon "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces/connect" - "time" ) type IbmCloudDriver struct{} @@ -38,6 +39,7 @@ func (IbmCloudDriver) GetDriverCapability() idrv.DriverCapabilityInfo { drvCapabilityInfo.NLBHandler = true drvCapabilityInfo.RegionZoneHandler = true drvCapabilityInfo.PriceInfoHandler = true + drvCapabilityInfo.TagHandler = true return drvCapabilityInfo } diff --git a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/connect/Ibm_CloudConnection.go b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/connect/Ibm_CloudConnection.go index 205a11115..ea980ba44 100644 --- a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/connect/Ibm_CloudConnection.go +++ b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/connect/Ibm_CloudConnection.go @@ -175,5 +175,12 @@ func (cloudConn *IbmCloudConnection) CreatePriceInfoHandler() (irs.PriceInfoHand } func (cloudConn *IbmCloudConnection) CreateTagHandler() (irs.TagHandler, error) { - return nil, errors.New("Ibm Driver: not implemented") + cblogger.Info("Ibm Cloud Driver: called CreateTagHandler()!") + TagHandler := ibmrs.IbmTagHandler{ + CredentialInfo: cloudConn.CredentialInfo, + Region: cloudConn.Region, + VpcService: cloudConn.VpcService, + Ctx: cloudConn.Ctx, + } + return &TagHandler, nil } diff --git a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/main/Test_Resources.go b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/main/Test_Resources.go index ecf1aea16..1300455e4 100644 --- a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/main/Test_Resources.go +++ b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/main/Test_Resources.go @@ -4,6 +4,11 @@ import ( "bufio" "errors" "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + cblog "github.com/cloud-barista/cb-log" ibm "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc" idrv "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces" @@ -11,10 +16,6 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/sirupsen/logrus" "gopkg.in/yaml.v3" - "io/ioutil" - "os" - "strconv" - "strings" ) type Config struct { @@ -256,7 +257,8 @@ func showTestHandlerInfo() { cblogger.Info("10. RegionZoneHandler") cblogger.Info("11. PriceInfoHandler") cblogger.Info("12. ClusterHandler") - cblogger.Info("13. Exit") + cblogger.Info("13. TagHandler") + cblogger.Info("14. Exit") cblogger.Info("==========================================================") } @@ -307,8 +309,11 @@ func getResourceHandler(resourceType string, config Config) (interface{}, error) resourceHandler, err = ibmCon.CreatePriceInfoHandler() case "cluster": resourceHandler, err = ibmCon.CreateClusterHandler() + case "tag": + resourceHandler, err = ibmCon.CreateTagHandler() } + return resourceHandler, nil } func testImageHandlerListPrint() { @@ -1716,6 +1721,118 @@ Loop: } } +func testTagHandlerListPrint() { + cblogger.Info("Test TagHandler") + cblogger.Info("0. Menu") + cblogger.Info("1. ListTag()") + cblogger.Info("2. GetTag()") + cblogger.Info("3. FindTag()") + cblogger.Info("4. AddTag()") + cblogger.Info("5. RemoveTag()") + cblogger.Info("6. Exit") +} + +func testTagHandler(config Config) { + resourceHandler, err := getResourceHandler("tag", config) + if err != nil { + cblogger.Error(err) + return + } + tagHandler := resourceHandler.(irs.TagHandler) + + testTagHandlerListPrint() +Loop: + for { + var commandNum int + inputCnt, err := fmt.Scan(&commandNum) + if err != nil { + cblogger.Error(err) + } + + if inputCnt == 1 { + switch commandNum { + case 0: + testTagHandlerListPrint() + case 1: + cblogger.Info("Start ListTag() ...") + if listTag, err := tagHandler.ListTag("VPC", irs.IID{NameId: "vpc-01-coadt9u8iqburq79175g",SystemId: "r006-6b9522df-6a21-47f3-8755-d8c217868367"}); err != nil { + cblogger.Error(err) + } else { + spew.Dump(listTag) + } + cblogger.Info("Finish listTag()") + case 2: + cblogger.Info("Start GetTag() ...") + var getTagName string + fmt.Print("Enter Get TagName: ") + if _, err := fmt.Scanln(&getTagName); err != nil { + cblogger.Error(err) + } + + if listTag, err := tagHandler.GetTag("VPC", irs.IID{NameId: "vpc-01-coadt9u8iqburq79175g",SystemId: "r006-6b9522df-6a21-47f3-8755-d8c217868367"}, getTagName); err != nil { + cblogger.Error(err) + } else { + spew.Dump(listTag) + } + cblogger.Info("Finish GetTag()") + case 3: + cblogger.Info("Start FindTag() ...") + var keyword string + fmt.Print("Enter keyword: ") + if _, err := fmt.Scanln(&keyword); err != nil { + cblogger.Error(err) + } + if listTag, err := tagHandler.FindTag("VPC", keyword); err != nil { + cblogger.Error(err) + } else { + spew.Dump(listTag) + } + cblogger.Info("Finish FindTag()") + case 4: + cblogger.Info("Start AddTag() ...") + var addKey string + var addValue string + + fmt.Print("Enter Add Key: ") + if _, err := fmt.Scanln(&addKey); err != nil { + cblogger.Error(err) + } + + fmt.Print("Enter Add Value: ") + if _, err := fmt.Scanln(&addValue); err != nil { + cblogger.Error(err) + } + + if listTag, err := tagHandler.AddTag("SecurityGroup", irs.IID{NameId: "sg01-coadudu8iqburq79176g",SystemId: "r006-a2fab93c-7964-4585-8900-9e13fbec4048"},irs.KeyValue{Key: addKey,Value: addValue}); err != nil { + cblogger.Error(err) + } else { + spew.Dump(listTag) + } + cblogger.Info("Finish AddTag()") + case 5: + cblogger.Info("Start RemoveTag() ...") + var removeKey string + fmt.Print("Enter Remove Key: ") + if _, err := fmt.Scanln(&removeKey); err != nil { + cblogger.Error(err) + } + + removeTagStatus, err := tagHandler.RemoveTag("VPC", irs.IID{NameId: "vpc-01-coadt9u8iqburq79175g",SystemId: "r006-6b9522df-6a21-47f3-8755-d8c217868367"}, removeKey) + if err != nil { + cblogger.Error(err) + } else { + spew.Dump(removeTagStatus) + } + cblogger.Info("Finish RemoveTag()") + case 6: + cblogger.Info("Exit") + break Loop + } + } + } +} + + func main() { showTestHandlerInfo() config := readConfigFile() @@ -1768,6 +1885,9 @@ Loop: testClusterHandler(config) showTestHandlerInfo() case 13: + testTagHandler(config) + showTestHandlerInfo() + case 14: cblogger.Info("Exit Test ResourceHandler Program") break Loop } diff --git a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/TagHandler.go b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/TagHandler.go new file mode 100644 index 000000000..22a8d4efc --- /dev/null +++ b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/TagHandler.go @@ -0,0 +1,487 @@ +package resources + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "log" + "strings" + + "github.com/IBM/go-sdk-core/v5/core" + "github.com/IBM/platform-services-go-sdk/globalsearchv2" + globalTaggingService "github.com/IBM/platform-services-go-sdk/globaltaggingv1" + "github.com/IBM/vpc-go-sdk/vpcv1" + idrv "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces" + irs "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces/resources" +) + +type IbmTagHandler struct { + Region idrv.RegionInfo + CredentialInfo idrv.CredentialInfo + VpcService *vpcv1.VpcV1 + Ctx context.Context +} + +type TagList struct { + TotalCount *int64 `json:"total_count"` + Offset *int64 `json:"offset"` + Limit *int64 `json:"limit"` + Items []Tag `json:"items"` +} + +type Tag struct { + Name *string `json:"name" validate:"required"` +} + +type TagResults struct { + Results []TagResultsItem `json:"results"` +} + +type TagResultsItem struct { + ResourceID *string `json:"resource_id" validate:"required"` + IsError *bool `json:"is_error"` +} + +type Item struct { + CRN string + Name string + Tags []interface{} + Type string +} + +// ListTag implements resources.TagHandler. +func (tagHandler *IbmTagHandler) ListTag(resType irs.RSType, resIID irs.IID) ([]irs.KeyValue, error) { + // IBM Cloud API Key 설정 + authenticator := &core.IamAuthenticator{ + ApiKey: tagHandler.CredentialInfo.ApiKey, + } + + // GlobalTaggingV1 인스턴스 생성 + service, err := globalTaggingService.NewGlobalTaggingV1(&globalTaggingService.GlobalTaggingV1Options{ + Authenticator: authenticator, + }) + if err != nil { + log.Fatalf("Failed to create service: %v", err) + } + + // ListTagsOptions 생성 + listTagsOptions := service.NewListTagsOptions() + listTagsOptions.SetTagType("user") + // listTagsOptions.SetAttachedOnly(false) // 리소스에 연결된 태그만 가져오기 + listTagsOptions.SetProviders([]string{"ghost"}) + listTagsOptions.SetOrderByName("asc") + + // ListTags 호출 + tagList, response, err := service.ListTags(listTagsOptions) + if err != nil { + panic(err) + } + + // 응답 디버깅 + if response != nil { + fmt.Printf("Response status code: %d\n", response.StatusCode) + } + + // 태그 데이터 파싱 + var tags []irs.KeyValue + + for _, tag := range tagList.Items { + tags = append(tags, irs.KeyValue{ + Key: *tag.Name, + Value: "", + }) + } + + // 디버그 출력 + b, _ := json.MarshalIndent(tagList, "", " ") + fmt.Println(string(b)) + + return tags, nil +} + +// GetTag implements resources.TagHandler. +func (tagHandler *IbmTagHandler) GetTag(resType irs.RSType, resIID irs.IID, key string) (irs.KeyValue, error) { + // IBM Cloud API Key 설정 + authenticator := &core.IamAuthenticator{ + ApiKey: tagHandler.CredentialInfo.ApiKey, + } + + // Create Global Search service instance + options := &globalsearchv2.GlobalSearchV2Options{ + Authenticator: authenticator, + } + service, err := globalsearchv2.NewGlobalSearchV2(options) + if err != nil { + fmt.Println("Error creating Global Search service:", err) + return irs.KeyValue{}, err + } + + // Define search options + searchOptions := service.NewSearchOptions() + // 검색 쿼리를 설정합니다. + resourceType := resType + resourceName := resIID.NameId + query := fmt.Sprintf("type:%s AND name:%s", resourceType, resourceName) + // searchQuery := resIID.SystemId + searchOptions.SetQuery(query) + searchOptions.SetFields([]string{"name","type","crn","tags"}) + searchOptions.SetLimit(100) + + // Call the service + scanResult, response, err := service.Search(searchOptions) + if err != nil { + fmt.Printf("Error searching for resources: %s\n", err.Error()) + if response != nil { + fmt.Printf("Response status code: %d\n", response.StatusCode) + fmt.Printf("Response headers: %v\n", response.Headers) + fmt.Printf("Response result: %v\n", response.Result) + } + return irs.KeyValue{}, err + } + + var result irs.KeyValue + // 결과 필터링 + for _, item := range scanResult.Items { + tags, ok := item.GetProperty("tags").([]interface{}) + if !ok { + fmt.Println("Error: Tags are not in expected format") + continue + } + for _, tag := range tags { + tagStr, ok := tag.(string) + if !ok { + fmt.Println("Error: Tag is not a string") + continue + } + + parts := strings.SplitN(tagStr, ":", 2) + if parts[0] == key { + result = irs.KeyValue{Key: parts[0], Value: parts[1]} + break + } + } + } + + // 응답 디버깅 + if response != nil { + fmt.Printf("Response status code: %d\n", response.StatusCode) + } + + return result, err +} + + +// FindTag implements resources.TagHandler. +func (tagHandler *IbmTagHandler) FindTag(resType irs.RSType, keyword string) ([]*irs.TagInfo, error) { + // IBM Cloud API Key 설정 + authenticator := &core.IamAuthenticator{ + ApiKey: tagHandler.CredentialInfo.ApiKey, + } + + // Create Global Search service instance + options := &globalsearchv2.GlobalSearchV2Options{ + Authenticator: authenticator, + } + service, err := globalsearchv2.NewGlobalSearchV2(options) + if err != nil { + fmt.Println("Error creating Global Search service:", err) + return nil, err + } + + // Define search options + searchOptions := service.NewSearchOptions() + // 검색 쿼리를 설정합니다. + resourceType := resType + query := fmt.Sprintf("type:%s", resourceType) + // searchQuery := resIID.SystemId + searchOptions.SetQuery(query) + searchOptions.SetFields([]string{"name","resource_id","type","crn","tags"}) + searchOptions.SetLimit(100) + + // Call the service + scanResult, response, err := service.Search(searchOptions) + if err != nil { + fmt.Printf("Error searching for resources: %s\n", err.Error()) + if response != nil { + fmt.Printf("Response status code: %d\n", response.StatusCode) + fmt.Printf("Response headers: %v\n", response.Headers) + fmt.Printf("Response result: %v\n", response.Result) + } + return nil, err + } + + var result []*irs.TagInfo + // 결과 필터링 + for _, item := range scanResult.Items { + matchedTag := []irs.KeyValue{} + tags, ok := item.GetProperty("tags").([]interface{}) + if !ok { + fmt.Println("Error: Tags are not in expected format") + continue + } + for _, tag := range tags { + tagStr, ok := tag.(string) + if !ok { + fmt.Println("Error: Tag is not a string") + continue + } + parts := strings.SplitN(tagStr, ":", 2) + Key := parts[0] + Value := parts[1] + + if Key == keyword || Value == keyword { + matchedTag = append(matchedTag, irs.KeyValue{Key: Key, Value: Value}) + } + } + if len(matchedTag) > 0 { + item.SetProperty("tags", matchedTag) + result = append(result, &irs.TagInfo{ + ResType: resType, + ResIId: irs.IID{NameId: (item.GetProperty("name")).(string),SystemId: (item.GetProperty("resource_id").(string))}, + TagList: matchedTag, + KeyValueList: matchedTag, + }) + } + } + + + + b, _ := json.MarshalIndent(result, "", " ") + fmt.Println(string(b)) + + // 응답 디버깅 + if response != nil { + fmt.Printf("Response status code: %d\n", response.StatusCode) + } + + return result, err +} + +// AddTag implements resources.TagHandler. +func (tagHandler *IbmTagHandler) AddTag(resType irs.RSType, resIID irs.IID, tag irs.KeyValue) (irs.KeyValue, error) { + switch resType { + case "VPC": + vpc, err := GetRawVPC(resIID, tagHandler.VpcService, tagHandler.Ctx) + if err != nil{ + log.Fatalf("Failed to Attach Tag: %v", err) + } + AttachTag(tagHandler.CredentialInfo.ApiKey, resIID, tag, *vpc.CRN) + case "Subnet": + vpc, err := GetRawVPC(resIID, tagHandler.VpcService, tagHandler.Ctx) + if err != nil{ + log.Fatalf("Failed to Attach Tag: %v", err) + } + + subnet, err := getVPCRawSubnet(vpc, resIID, tagHandler.VpcService, tagHandler.Ctx) + if err != nil{ + log.Fatalf("Failed to Attach Tag: %v", err) + } + AttachTag(tagHandler.CredentialInfo.ApiKey, resIID, tag, *subnet.CRN) + case "SecurityGroup": + securityGroup, err := getRawSecurityGroup(resIID, tagHandler.VpcService, tagHandler.Ctx) + if err != nil{ + log.Fatalf("Failed to Attach Tag: %v", err) + } + fmt.Println(securityGroup) + AttachTag(tagHandler.CredentialInfo.ApiKey, resIID, tag, *securityGroup.CRN) + case "VMKeyPair": + vmKeyPair, err := getRawKey(resIID, tagHandler.VpcService, tagHandler.Ctx) + if err != nil{ + log.Fatalf("Failed to Attach Tag: %v", err) + } + AttachTag(tagHandler.CredentialInfo.ApiKey, resIID, tag, *vmKeyPair.CRN) + case "VM": + vm, err := getRawInstance(resIID, tagHandler.VpcService, tagHandler.Ctx) + if err != nil{ + log.Fatalf("Failed to Attach Tag: %v", err) + } + AttachTag(tagHandler.CredentialInfo.ApiKey, resIID, tag, *vm.CRN) + case "Disk": + disk, err := getRawVolume(resIID, tagHandler.VpcService, tagHandler.Ctx) + if err != nil{ + log.Fatalf("Failed to Attach Tag: %v", err) + } + AttachTag(tagHandler.CredentialInfo.ApiKey, resIID, tag, *disk.CRN) + // case "MyImage": + // imageHandler := &IbmMyImageHandler{} + // rawMyimage, err := imageHandler.GetMyImage(resIID) + // if err != nil { + // getErr := errors.New(fmt.Sprintf("Failed to Get NLB. err = %s", err.Error())) + // cblogger.Error(getErr.Error()) + // } + // AttachTag(tagHandler.CredentialInfo.ApiKey, resIID, tag, *rawMyimage.CRN) + case "NLB": + nlbHandler := &IbmNLBHandler{} // or however you initialize IbmNLBHandler + rawNLB, err := nlbHandler.getRawNLBByName(resIID.NameId) + if err != nil { + getErr := errors.New(fmt.Sprintf("Failed to Get NLB. err = %s", err.Error())) + cblogger.Error(getErr.Error()) + } + AttachTag(tagHandler.CredentialInfo.ApiKey, resIID, tag, *rawNLB.CRN) + } + + return irs.KeyValue{Key: tag.Key, Value: tag.Value}, nil +} + +// RemoveTag implements resources.TagHandler. +func (tagHandler *IbmTagHandler) RemoveTag(resType irs.RSType, resIID irs.IID, tagName string) (bool, error) { + switch resType { + case "VPC": + vpc, err := GetRawVPC(resIID, tagHandler.VpcService, tagHandler.Ctx) + if err != nil{ + log.Fatalf("Failed to Attach Tag: %v", err) + } + DetachTag(tagHandler.CredentialInfo.ApiKey, resIID, tagName, *vpc.CRN) + case "Subnet": + vpc, err := GetRawVPC(resIID, tagHandler.VpcService, tagHandler.Ctx) + if err != nil{ + log.Fatalf("Failed to Attach Tag: %v", err) + } + + subnet, err := getVPCRawSubnet(vpc, resIID, tagHandler.VpcService, tagHandler.Ctx) + if err != nil{ + log.Fatalf("Failed to Attach Tag: %v", err) + } + DetachTag(tagHandler.CredentialInfo.ApiKey, resIID, tagName, *subnet.CRN) + case "SecurityGroup": + securityGroup, err := getRawSecurityGroup(resIID, tagHandler.VpcService, tagHandler.Ctx) + if err != nil{ + log.Fatalf("Failed to Attach Tag: %v", err) + } + DetachTag(tagHandler.CredentialInfo.ApiKey, resIID, tagName, *securityGroup.CRN) + case "VMKeyPair": + vmKeyPair, err := getRawKey(resIID, tagHandler.VpcService, tagHandler.Ctx) + if err != nil{ + log.Fatalf("Failed to Attach Tag: %v", err) + } + DetachTag(tagHandler.CredentialInfo.ApiKey, resIID, tagName, *vmKeyPair.CRN) + case "VM": + vm, err := getRawInstance(resIID, tagHandler.VpcService, tagHandler.Ctx) + if err != nil{ + log.Fatalf("Failed to Attach Tag: %v", err) + } + DetachTag(tagHandler.CredentialInfo.ApiKey, resIID, tagName, *vm.CRN) + case "Disk": + disk, err := getRawVolume(resIID, tagHandler.VpcService, tagHandler.Ctx) + if err != nil{ + log.Fatalf("Failed to Attach Tag: %v", err) + } + DetachTag(tagHandler.CredentialInfo.ApiKey, resIID, tagName, *disk.CRN) + // case "MyImage": + // myImageHandler := &IbmMyImageHandler{} + // rawMyimage, err := myImageHandler.GetMyImage(resIID) + // if err != nil { + // getErr := errors.New(fmt.Sprintf("Failed to Get NLB. err = %s", err.Error())) + // cblogger.Error(getErr.Error()) + // } + // DetachTag(tagHandler.CredentialInfo.ApiKey, resIID, tagName, *rawMyimage.CRN) + case "NLB": + nlbHandler := &IbmNLBHandler{} // or however you initialize IbmNLBHandler + rawNLB, err := nlbHandler.getRawNLBByName(resIID.NameId) + if err != nil { + getErr := errors.New(fmt.Sprintf("Failed to Get NLB. err = %s", err.Error())) + cblogger.Error(getErr.Error()) + } + DetachTag(tagHandler.CredentialInfo.ApiKey, resIID, tagName, *rawNLB.CRN) + } + + return true, nil +} + +func AttachTag (apikey string, resIID irs.IID, tag irs.KeyValue, CRN string){ + // IBM Cloud API Key 설정 + authenticator := &core.IamAuthenticator{ + ApiKey: apikey, + } + + // GlobalTaggingV1 인스턴스 생성 + service, err := globalTaggingService.NewGlobalTaggingV1(&globalTaggingService.GlobalTaggingV1Options{ + Authenticator: authenticator, + }) + if err != nil { + fmt.Errorf("failed to create service: %w", err) + } + + resourceModel := globalTaggingService.Resource{ + ResourceID: &CRN, + } + + attachTagOptions := service.NewAttachTagOptions( + []globalTaggingService.Resource{resourceModel}, + ) + + tagName := "" + if tag.Value == "" { + tagName = tag.Key + } else { + tagName = tag.Key + ":" + tag.Value + } + + attachTagOptions.SetTagNames([]string{tagName}) + attachTagOptions.SetTagType("user") + + tagResults, response, err := service.AttachTag(attachTagOptions) + if err != nil { + } + + // 응답 디버깅 + if response != nil { + fmt.Printf("Response status code: %d\n", response.StatusCode) + } + + b, _ := json.MarshalIndent(tagResults, "", " ") + fmt.Println(string(b)) +} + +func DetachTag (apikey string, resIID irs.IID, tagName string, CRN string){ + // IBM Cloud API Key 설정 + authenticator := &core.IamAuthenticator{ + ApiKey: apikey, + } + + // GlobalTaggingV1 인스턴스 생성 + service, err := globalTaggingService.NewGlobalTaggingV1(&globalTaggingService.GlobalTaggingV1Options{ + Authenticator: authenticator, + }) + if err != nil { + fmt.Errorf("failed to delete service: %w", err) + } + + // Detach 진행 + resourceCRN := CRN + resourceModel := globalTaggingService.Resource{ + ResourceID: &resourceCRN, + } + + detachTagOptions := service.NewDetachTagOptions( + []globalTaggingService.Resource{resourceModel}, + ) + + detachTagOptions.SetTagNames([]string{tagName}) + detachTagOptions.SetTagType("user") + + detachTagResults, response, err := service.DetachTag(detachTagOptions) + if err != nil { + log.Fatalf("Failed to delete service: %v", err) + } + b, _ := json.MarshalIndent(detachTagResults, "", " ") + fmt.Println(string(b)) + + // Delete 진행 + deleteTagOptions := service.NewDeleteTagOptions(tagName) + deleteTagOptions.SetTagType("user") + + deleteTagResults, response, err := service.DeleteTag(deleteTagOptions) + if err != nil { + log.Fatalf("Failed to delete service: %v", err) + } + + b, _ = json.MarshalIndent(deleteTagResults, "", " ") + fmt.Println(string(b)) + + // 응답 디버깅 + if response != nil { + fmt.Printf("Response status code: %d\n", response.StatusCode) + } +} \ No newline at end of file From 28b40c8b44c56a85c21f2a6c93f1eb316355bdf2 Mon Sep 17 00:00:00 2001 From: ish Date: Thu, 25 Jul 2024 20:38:27 +0900 Subject: [PATCH 22/32] IBM: Fix TagHandler --- .../drivers/ibmcloud-vpc/IBMCloudDriver.go | 10 + .../connect/Ibm_CloudConnection.go | 4 + .../ibmcloud-vpc/main/Test_Resources.go | 226 ++++- .../ibmcloud-vpc/resources/TagHandler.go | 775 +++++++++--------- .../ibmcloud-vpc/resources/VPCHandler.go | 44 + 5 files changed, 650 insertions(+), 409 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/IBMCloudDriver.go b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/IBMCloudDriver.go index 391797c48..aabd510d9 100644 --- a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/IBMCloudDriver.go +++ b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/IBMCloudDriver.go @@ -3,6 +3,7 @@ package ibmcloudvpc import ( "context" "errors" + "github.com/IBM/platform-services-go-sdk/globalsearchv2" "time" "github.com/IBM/go-sdk-core/v5/core" @@ -111,6 +112,14 @@ func (driver *IbmCloudDriver) ConnectCloud(connectionInfo idrv.ConnectionInfo) ( if err != nil { return nil, err } + searchService, err := globalsearchv2.NewGlobalSearchV2(&globalsearchv2.GlobalSearchV2Options{ + Authenticator: &core.IamAuthenticator{ + ApiKey: connectionInfo.CredentialInfo.ApiKey, + }, + }) + if err != nil { + return nil, err + } iConn := connect.IbmCloudConnection{ CredentialInfo: connectionInfo.CredentialInfo, @@ -119,6 +128,7 @@ func (driver *IbmCloudDriver) ConnectCloud(connectionInfo idrv.ConnectionInfo) ( VpcService0230: vpcService0230, ClusterService: clusterService, TaggingService: taggingService, + SearchService: searchService, Ctx: ctx, } return &iConn, nil diff --git a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/connect/Ibm_CloudConnection.go b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/connect/Ibm_CloudConnection.go index ea980ba44..959c8b8af 100644 --- a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/connect/Ibm_CloudConnection.go +++ b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/connect/Ibm_CloudConnection.go @@ -3,6 +3,7 @@ package connect import ( "context" "errors" + "github.com/IBM/platform-services-go-sdk/globalsearchv2" "github.com/IBM/platform-services-go-sdk/globaltaggingv1" vpcv0230 "github.com/IBM/vpc-go-sdk/0.23.0/vpcv1" @@ -28,6 +29,7 @@ type IbmCloudConnection struct { VpcService *vpcv1.VpcV1 ClusterService *kubernetesserviceapiv1.KubernetesServiceApiV1 TaggingService *globaltaggingv1.GlobalTaggingV1 + SearchService *globalsearchv2.GlobalSearchV2 VpcService0230 *vpcv0230.VpcV1 Ctx context.Context } @@ -181,6 +183,8 @@ func (cloudConn *IbmCloudConnection) CreateTagHandler() (irs.TagHandler, error) Region: cloudConn.Region, VpcService: cloudConn.VpcService, Ctx: cloudConn.Ctx, + TaggingService: cloudConn.TaggingService, + SearchService: cloudConn.SearchService, } return &TagHandler, nil } diff --git a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/main/Test_Resources.go b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/main/Test_Resources.go index 1300455e4..05e4e1cb6 100644 --- a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/main/Test_Resources.go +++ b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/main/Test_Resources.go @@ -313,7 +313,6 @@ func getResourceHandler(resourceType string, config Config) (interface{}, error) resourceHandler, err = ibmCon.CreateTagHandler() } - return resourceHandler, nil } func testImageHandlerListPrint() { @@ -1723,15 +1722,46 @@ Loop: func testTagHandlerListPrint() { cblogger.Info("Test TagHandler") - cblogger.Info("0. Menu") - cblogger.Info("1. ListTag()") - cblogger.Info("2. GetTag()") - cblogger.Info("3. FindTag()") - cblogger.Info("4. AddTag()") - cblogger.Info("5. RemoveTag()") + cblogger.Info("0. Print Menu") + cblogger.Info("1. AddTag()") + cblogger.Info("2. ListTag()") + cblogger.Info("3. GetTag()") + cblogger.Info("4. RemoveTag()") + cblogger.Info("5. FindTag()") cblogger.Info("6. Exit") } +func inputToRSType(input string) irs.RSType { + switch input { + case "all": + return irs.ALL + case "image": + return irs.IMAGE + case "vpc": + return irs.VPC + case "subnet": + return irs.SUBNET + case "sg": + return irs.SG + case "keypair": + return irs.KEY + case "vm": + return irs.VM + case "nlb": + return irs.NLB + case "disk": + return irs.DISK + case "myimage": + return irs.MYIMAGE + case "cluster": + return irs.CLUSTER + case "nodegroup": + return irs.NODEGROUP + default: + return "" + } +} + func testTagHandler(config Config) { resourceHandler, err := getResourceHandler("tag", config) if err != nil { @@ -1754,76 +1784,187 @@ Loop: case 0: testTagHandlerListPrint() case 1: - cblogger.Info("Start ListTag() ...") - if listTag, err := tagHandler.ListTag("VPC", irs.IID{NameId: "vpc-01-coadt9u8iqburq79175g",SystemId: "r006-6b9522df-6a21-47f3-8755-d8c217868367"}); err != nil { + cblogger.Info("Start AddTag() ...") + fmt.Println("=== Enter resource type ===") + in := bufio.NewReader(os.Stdin) + resTypeStr, err := in.ReadString('\n') + if err != nil { + cblogger.Error(err) + } + resTypeStr = strings.TrimSpace(resTypeStr) + result := irs.RSTypeString(irs.RSType(resTypeStr)) + if strings.Contains(result, "not supported") { + cblogger.Error(result) + break Loop + } + resType := inputToRSType(resTypeStr) + + fmt.Println("=== Enter name of the resource ===") + in = bufio.NewReader(os.Stdin) + resName, err := in.ReadString('\n') + if err != nil { + cblogger.Error(err) + } + resName = strings.TrimSpace(resName) + + fmt.Println("=== Enter tag's key ===") + in = bufio.NewReader(os.Stdin) + tagKey, err := in.ReadString('\n') + if err != nil { + cblogger.Error(err) + } + tagKey = strings.TrimSpace(tagKey) + + fmt.Println("=== Enter tag's value ===") + in = bufio.NewReader(os.Stdin) + tagValue, err := in.ReadString('\n') + if err != nil { + cblogger.Error(err) + } + tagValue = strings.TrimSpace(tagValue) + + if tagKeyValue, err := tagHandler.AddTag(resType, irs.IID{NameId: resName}, irs.KeyValue{Key: tagKey, Value: tagValue}); err != nil { cblogger.Error(err) } else { - spew.Dump(listTag) + spew.Dump(tagKeyValue) } - cblogger.Info("Finish listTag()") + cblogger.Info("Finish AddTag()") case 2: - cblogger.Info("Start GetTag() ...") - var getTagName string - fmt.Print("Enter Get TagName: ") - if _, err := fmt.Scanln(&getTagName); err != nil { + cblogger.Info("Start ListTag() ...") + fmt.Println("=== Enter resource type ===") + in := bufio.NewReader(os.Stdin) + resTypeStr, err := in.ReadString('\n') + if err != nil { + cblogger.Error(err) + } + resTypeStr = strings.TrimSpace(resTypeStr) + result := irs.RSTypeString(irs.RSType(resTypeStr)) + if strings.Contains(result, "not supported") { + cblogger.Error(result) + break Loop + } + resType := inputToRSType(resTypeStr) + + fmt.Println("=== Enter name of the resource ===") + in = bufio.NewReader(os.Stdin) + resName, err := in.ReadString('\n') + if err != nil { cblogger.Error(err) } + resName = strings.TrimSpace(resName) - if listTag, err := tagHandler.GetTag("VPC", irs.IID{NameId: "vpc-01-coadt9u8iqburq79175g",SystemId: "r006-6b9522df-6a21-47f3-8755-d8c217868367"}, getTagName); err != nil { + if tagList, err := tagHandler.ListTag(resType, irs.IID{NameId: resName}); err != nil { cblogger.Error(err) } else { - spew.Dump(listTag) + spew.Dump(tagList) } - cblogger.Info("Finish GetTag()") + cblogger.Info("Finish ListTag()") case 3: - cblogger.Info("Start FindTag() ...") - var keyword string - fmt.Print("Enter keyword: ") - if _, err := fmt.Scanln(&keyword); err != nil { + cblogger.Info("Start GetTag() ...") + fmt.Println("=== Enter resource type ===") + in := bufio.NewReader(os.Stdin) + resTypeStr, err := in.ReadString('\n') + if err != nil { cblogger.Error(err) } - if listTag, err := tagHandler.FindTag("VPC", keyword); err != nil { + resTypeStr = strings.TrimSpace(resTypeStr) + result := irs.RSTypeString(irs.RSType(resTypeStr)) + if strings.Contains(result, "not supported") { + cblogger.Error(result) + break Loop + } + resType := inputToRSType(resTypeStr) + + fmt.Println("=== Enter name of the resource ===") + in = bufio.NewReader(os.Stdin) + resName, err := in.ReadString('\n') + if err != nil { + cblogger.Error(err) + } + resName = strings.TrimSpace(resName) + + fmt.Println("=== Enter tag's key ===") + in = bufio.NewReader(os.Stdin) + tagKey, err := in.ReadString('\n') + if err != nil { + cblogger.Error(err) + } + tagKey = strings.TrimSpace(tagKey) + + if tagKeyValue, err := tagHandler.GetTag(resType, irs.IID{NameId: resName}, tagKey); err != nil { cblogger.Error(err) } else { - spew.Dump(listTag) + spew.Dump(tagKeyValue) } - cblogger.Info("Finish FindTag()") + cblogger.Info("Finish GetTag()") case 4: - cblogger.Info("Start AddTag() ...") - var addKey string - var addValue string + cblogger.Info("Start RemoveTag() ...") + fmt.Println("=== Enter resource type ===") + in := bufio.NewReader(os.Stdin) + resTypeStr, err := in.ReadString('\n') + if err != nil { + cblogger.Error(err) + } + resTypeStr = strings.TrimSpace(resTypeStr) + result := irs.RSTypeString(irs.RSType(resTypeStr)) + if strings.Contains(result, "not supported") { + cblogger.Error(result) + break Loop + } + resType := inputToRSType(resTypeStr) - fmt.Print("Enter Add Key: ") - if _, err := fmt.Scanln(&addKey); err != nil { + fmt.Println("=== Enter name of the resource ===") + in = bufio.NewReader(os.Stdin) + resName, err := in.ReadString('\n') + if err != nil { cblogger.Error(err) } + resName = strings.TrimSpace(resName) - fmt.Print("Enter Add Value: ") - if _, err := fmt.Scanln(&addValue); err != nil { + fmt.Println("=== Enter tag's key ===") + in = bufio.NewReader(os.Stdin) + tagKey, err := in.ReadString('\n') + if err != nil { cblogger.Error(err) } + tagKey = strings.TrimSpace(tagKey) - if listTag, err := tagHandler.AddTag("SecurityGroup", irs.IID{NameId: "sg01-coadudu8iqburq79176g",SystemId: "r006-a2fab93c-7964-4585-8900-9e13fbec4048"},irs.KeyValue{Key: addKey,Value: addValue}); err != nil { + if tagKeyValue, err := tagHandler.RemoveTag(resType, irs.IID{NameId: resName}, tagKey); err != nil { cblogger.Error(err) } else { - spew.Dump(listTag) + spew.Dump(tagKeyValue) } - cblogger.Info("Finish AddTag()") + cblogger.Info("Finish RemoveTag()") case 5: - cblogger.Info("Start RemoveTag() ...") - var removeKey string - fmt.Print("Enter Remove Key: ") - if _, err := fmt.Scanln(&removeKey); err != nil { + cblogger.Info("Start FindTag() ...") + fmt.Println("=== Enter resource type ===") + in := bufio.NewReader(os.Stdin) + resTypeStr, err := in.ReadString('\n') + if err != nil { cblogger.Error(err) } + resTypeStr = strings.TrimSpace(resTypeStr) + result := irs.RSTypeString(irs.RSType(resTypeStr)) + if strings.Contains(result, "not supported") { + cblogger.Error(result) + break Loop + } + resType := inputToRSType(resTypeStr) - removeTagStatus, err := tagHandler.RemoveTag("VPC", irs.IID{NameId: "vpc-01-coadt9u8iqburq79175g",SystemId: "r006-6b9522df-6a21-47f3-8755-d8c217868367"}, removeKey) + fmt.Println("=== Enter keyword ===") + in = bufio.NewReader(os.Stdin) + keyword, err := in.ReadString('\n') if err != nil { cblogger.Error(err) + } + keyword = strings.TrimSpace(keyword) + + if tagKeyValue, err := tagHandler.FindTag(resType, keyword); err != nil { + cblogger.Error(err) } else { - spew.Dump(removeTagStatus) + spew.Dump(tagKeyValue) } - cblogger.Info("Finish RemoveTag()") + cblogger.Info("Finish FindTag()") case 6: cblogger.Info("Exit") break Loop @@ -1832,7 +1973,6 @@ Loop: } } - func main() { showTestHandlerInfo() config := readConfigFile() diff --git a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/TagHandler.go b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/TagHandler.go index 22a8d4efc..c74ca800c 100644 --- a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/TagHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/TagHandler.go @@ -2,25 +2,25 @@ package resources import ( "context" - "encoding/json" "errors" "fmt" - "log" + call "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/call-log" "strings" - "github.com/IBM/go-sdk-core/v5/core" "github.com/IBM/platform-services-go-sdk/globalsearchv2" - globalTaggingService "github.com/IBM/platform-services-go-sdk/globaltaggingv1" + "github.com/IBM/platform-services-go-sdk/globaltaggingv1" "github.com/IBM/vpc-go-sdk/vpcv1" idrv "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces" irs "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces/resources" ) type IbmTagHandler struct { - Region idrv.RegionInfo - CredentialInfo idrv.CredentialInfo - VpcService *vpcv1.VpcV1 - Ctx context.Context + Region idrv.RegionInfo + CredentialInfo idrv.CredentialInfo + VpcService *vpcv1.VpcV1 + Ctx context.Context + TaggingService *globaltaggingv1.GlobalTaggingV1 + SearchService *globalsearchv2.GlobalSearchV2 } type TagList struct { @@ -44,444 +44,487 @@ type TagResultsItem struct { } type Item struct { - CRN string - Name string - Tags []interface{} - Type string + CRN string + Name string + Tags []interface{} + Type string } -// ListTag implements resources.TagHandler. -func (tagHandler *IbmTagHandler) ListTag(resType irs.RSType, resIID irs.IID) ([]irs.KeyValue, error) { - // IBM Cloud API Key 설정 - authenticator := &core.IamAuthenticator{ - ApiKey: tagHandler.CredentialInfo.ApiKey, - } - - // GlobalTaggingV1 인스턴스 생성 - service, err := globalTaggingService.NewGlobalTaggingV1(&globalTaggingService.GlobalTaggingV1Options{ - Authenticator: authenticator, - }) - if err != nil { - log.Fatalf("Failed to create service: %v", err) - } - - // ListTagsOptions 생성 - listTagsOptions := service.NewListTagsOptions() - listTagsOptions.SetTagType("user") - // listTagsOptions.SetAttachedOnly(false) // 리소스에 연결된 태그만 가져오기 - listTagsOptions.SetProviders([]string{"ghost"}) - listTagsOptions.SetOrderByName("asc") - - // ListTags 호출 - tagList, response, err := service.ListTags(listTagsOptions) - if err != nil { - panic(err) - } - - // 응답 디버깅 - if response != nil { - fmt.Printf("Response status code: %d\n", response.StatusCode) - } - - // 태그 데이터 파싱 - var tags []irs.KeyValue - - for _, tag := range tagList.Items { - tags = append(tags, irs.KeyValue{ - Key: *tag.Name, - Value: "", - }) - } - - // 디버그 출력 - b, _ := json.MarshalIndent(tagList, "", " ") - fmt.Println(string(b)) - - return tags, nil +func rsTypeToIBMType(resType irs.RSType) string { + switch resType { + case irs.ALL: + return "*" + case irs.IMAGE: + return "image" + case irs.VPC: + return "vpc" + case irs.SUBNET: + return "subnet" + case irs.SG: + return "security-group" + case irs.KEY: + return "key" + case irs.VM: + return "instance" + case irs.NLB: + return "load-balancer" + case irs.DISK: + return "volume" + case irs.MYIMAGE: + return "snapshot" + case irs.CLUSTER: + return "" + case irs.NODEGROUP: + return "instance-group" + default: + return "" + } } -// GetTag implements resources.TagHandler. -func (tagHandler *IbmTagHandler) GetTag(resType irs.RSType, resIID irs.IID, key string) (irs.KeyValue, error) { - // IBM Cloud API Key 설정 - authenticator := &core.IamAuthenticator{ - ApiKey: tagHandler.CredentialInfo.ApiKey, +func ibmTypeToRSType(ibmType string) (irs.RSType, error) { + fmt.Println(ibmType) + + switch ibmType { + case "image": + return irs.IMAGE, nil + case "vpc": + return irs.VPC, nil + case "subnet": + return irs.SUBNET, nil + case "security-group": + return irs.SG, nil + case "key": + return irs.KEY, nil + case "instance": + return irs.VM, nil + case "load-balancer": + return irs.NLB, nil + case "volume": + return irs.DISK, nil + case "snapshot": + return irs.MYIMAGE, nil + //case "???": + // return irs.CLUSTER + case "instance-group": + return irs.NODEGROUP, nil + default: + return "", errors.New(fmt.Sprintf("unsupport type %s", ibmType)) } +} - // Create Global Search service instance - options := &globalsearchv2.GlobalSearchV2Options{ - Authenticator: authenticator, +func getTagFromResource(searchService *globalsearchv2.GlobalSearchV2, + resType irs.RSType, resIID irs.IID, key string) (irs.KeyValue, error) { + searchOptions := searchService.NewSearchOptions() + + var query string + + ibmType := rsTypeToIBMType(resType) + if ibmType == "" { + return irs.KeyValue{}, errors.New("invalid resource type") } - service, err := globalsearchv2.NewGlobalSearchV2(options) - if err != nil { - fmt.Println("Error creating Global Search service:", err) - return irs.KeyValue{}, err + + if resIID.NameId != "" { + query = fmt.Sprintf("type:%s AND name:%s", ibmType, resIID.NameId) + } else { + query = fmt.Sprintf("type:%s AND id:%s", ibmType, resIID.SystemId) } - // Define search options - searchOptions := service.NewSearchOptions() - // 검색 쿼리를 설정합니다. - resourceType := resType - resourceName := resIID.NameId - query := fmt.Sprintf("type:%s AND name:%s", resourceType, resourceName) - // searchQuery := resIID.SystemId searchOptions.SetQuery(query) - searchOptions.SetFields([]string{"name","type","crn","tags"}) + searchOptions.SearchCursor = nil + searchOptions.SetFields([]string{"name", "type", "crn", "tags"}) searchOptions.SetLimit(100) - // Call the service - scanResult, response, err := service.Search(searchOptions) - if err != nil { - fmt.Printf("Error searching for resources: %s\n", err.Error()) - if response != nil { - fmt.Printf("Response status code: %d\n", response.StatusCode) - fmt.Printf("Response headers: %v\n", response.Headers) - fmt.Printf("Response result: %v\n", response.Result) + for { + scanResult, _, err := searchService.Search(searchOptions) + if err != nil { + return irs.KeyValue{}, err + } + + if len(scanResult.Items) == 0 { + break } - return irs.KeyValue{}, err - } - var result irs.KeyValue - // 결과 필터링 - for _, item := range scanResult.Items { - tags, ok := item.GetProperty("tags").([]interface{}) - if !ok { - fmt.Println("Error: Tags are not in expected format") - continue - } - for _, tag := range tags { - tagStr, ok := tag.(string) - if !ok { - fmt.Println("Error: Tag is not a string") - continue - } - - parts := strings.SplitN(tagStr, ":", 2) - if parts[0] == key { - result = irs.KeyValue{Key: parts[0], Value: parts[1]} - break - } - } - } - - // 응답 디버깅 - if response != nil { - fmt.Printf("Response status code: %d\n", response.StatusCode) + searchOptions.SearchCursor = scanResult.SearchCursor + + for _, item := range scanResult.Items { + tags, ok := item.GetProperty("tags").([]interface{}) + if !ok { + cblogger.Error("Tags are not in expected format") + continue + } + for _, tag := range tags { + tagStr, ok := tag.(string) + if !ok { + cblogger.Errorf("Tag is not a string (%v)", tag) + continue + } + + parts := strings.SplitN(tagStr, ":", 2) + if parts[0] == key { + return irs.KeyValue{Key: parts[0], Value: parts[1]}, nil + } + } + } } - return result, err + return irs.KeyValue{}, errors.New("tag not found") } - -// FindTag implements resources.TagHandler. -func (tagHandler *IbmTagHandler) FindTag(resType irs.RSType, keyword string) ([]*irs.TagInfo, error) { - // IBM Cloud API Key 설정 - authenticator := &core.IamAuthenticator{ - ApiKey: tagHandler.CredentialInfo.ApiKey, +func attachOrDetachTag(tagService *globaltaggingv1.GlobalTaggingV1, tag irs.KeyValue, CRN string, action string) error { + resourceModel := globaltaggingv1.Resource{ + ResourceID: &CRN, } - // Create Global Search service instance - options := &globalsearchv2.GlobalSearchV2Options{ - Authenticator: authenticator, - } - service, err := globalsearchv2.NewGlobalSearchV2(options) - if err != nil { - fmt.Println("Error creating Global Search service:", err) - return nil, err + var tagName string + if tag.Value == "" { + tagName = tag.Key + } else { + tagName = tag.Key + ":" + tag.Value } - // Define search options - searchOptions := service.NewSearchOptions() - // 검색 쿼리를 설정합니다. - resourceType := resType - query := fmt.Sprintf("type:%s", resourceType) - // searchQuery := resIID.SystemId - searchOptions.SetQuery(query) - searchOptions.SetFields([]string{"name","resource_id","type","crn","tags"}) - searchOptions.SetLimit(100) + switch action { + case "add": + attachTagOptions := tagService.NewAttachTagOptions( + []globaltaggingv1.Resource{resourceModel}, + ) - // Call the service - scanResult, response, err := service.Search(searchOptions) - if err != nil { - fmt.Printf("Error searching for resources: %s\n", err.Error()) - if response != nil { - fmt.Printf("Response status code: %d\n", response.StatusCode) - fmt.Printf("Response headers: %v\n", response.Headers) - fmt.Printf("Response result: %v\n", response.Result) - } - return nil, err - } + attachTagOptions.SetTagNames([]string{tagName}) + attachTagOptions.SetTagType("user") - var result []*irs.TagInfo - // 결과 필터링 - for _, item := range scanResult.Items { - matchedTag := []irs.KeyValue{} - tags, ok := item.GetProperty("tags").([]interface{}) - if !ok { - fmt.Println("Error: Tags are not in expected format") - continue - } - for _, tag := range tags { - tagStr, ok := tag.(string) - if !ok { - fmt.Println("Error: Tag is not a string") - continue - } - parts := strings.SplitN(tagStr, ":", 2) - Key := parts[0] - Value := parts[1] - - if Key == keyword || Value == keyword { - matchedTag = append(matchedTag, irs.KeyValue{Key: Key, Value: Value}) - } - } - if len(matchedTag) > 0 { - item.SetProperty("tags", matchedTag) - result = append(result, &irs.TagInfo{ - ResType: resType, - ResIId: irs.IID{NameId: (item.GetProperty("name")).(string),SystemId: (item.GetProperty("resource_id").(string))}, - TagList: matchedTag, - KeyValueList: matchedTag, - }) + _, _, err := tagService.AttachTag(attachTagOptions) + if err != nil { + return err } - } + case "remove": + detachTagOptions := tagService.NewDetachTagOptions( + []globaltaggingv1.Resource{resourceModel}, + ) + detachTagOptions.SetTagNames([]string{tagName}) + detachTagOptions.SetTagType("user") + _, _, err := tagService.DetachTag(detachTagOptions) + if err != nil { + return err + } - b, _ := json.MarshalIndent(result, "", " ") - fmt.Println(string(b)) + deleteTagAllOptions := tagService.NewDeleteTagAllOptions() + deleteTagAllOptions.SetTagType("user") - // 응답 디버깅 - if response != nil { - fmt.Printf("Response status code: %d\n", response.StatusCode) + _, _, err = tagService.DeleteTagAll(deleteTagAllOptions) + if err != nil { + return err + } } - return result, err + return nil } -// AddTag implements resources.TagHandler. -func (tagHandler *IbmTagHandler) AddTag(resType irs.RSType, resIID irs.IID, tag irs.KeyValue) (irs.KeyValue, error) { +func handleTagAddOrRemove(tagHandler *IbmTagHandler, resType irs.RSType, resIID irs.IID, + tag irs.KeyValue, action string) error { + var err2 error + + if action == "remove" { + tag, err2 = getTagFromResource(tagHandler.SearchService, resType, resIID, tag.Key) + if err2 != nil { + return err2 + } + } + + ibmType := rsTypeToIBMType(resType) + if ibmType == "" { + return errors.New("invalid resource type") + } else if ibmType == "all" { + return errors.New("all is not supported for getting tag from the resource") + } + switch resType { - case "VPC": + case irs.VPC: vpc, err := GetRawVPC(resIID, tagHandler.VpcService, tagHandler.Ctx) - if err != nil{ - log.Fatalf("Failed to Attach Tag: %v", err) + if err != nil { + err2 = errors.New(fmt.Sprintf("Failed to add tag. err = %s", err)) + break } - AttachTag(tagHandler.CredentialInfo.ApiKey, resIID, tag, *vpc.CRN) - case "Subnet": - vpc, err := GetRawVPC(resIID, tagHandler.VpcService, tagHandler.Ctx) - if err != nil{ - log.Fatalf("Failed to Attach Tag: %v", err) + err2 = attachOrDetachTag(tagHandler.TaggingService, tag, *vpc.CRN, action) + case irs.SUBNET: + subnet, err := getRawSubnet(resIID, tagHandler.VpcService, tagHandler.Ctx) + if err != nil { + err2 = errors.New(fmt.Sprintf("Failed to add tag. err = %s", err)) + break } - subnet, err := getVPCRawSubnet(vpc, resIID, tagHandler.VpcService, tagHandler.Ctx) - if err != nil{ - log.Fatalf("Failed to Attach Tag: %v", err) - } - AttachTag(tagHandler.CredentialInfo.ApiKey, resIID, tag, *subnet.CRN) - case "SecurityGroup": + err2 = attachOrDetachTag(tagHandler.TaggingService, tag, *subnet.CRN, action) + case irs.SG: securityGroup, err := getRawSecurityGroup(resIID, tagHandler.VpcService, tagHandler.Ctx) - if err != nil{ - log.Fatalf("Failed to Attach Tag: %v", err) + if err != nil { + err2 = errors.New(fmt.Sprintf("Failed to add tag. err = %s", err)) + break } - fmt.Println(securityGroup) - AttachTag(tagHandler.CredentialInfo.ApiKey, resIID, tag, *securityGroup.CRN) - case "VMKeyPair": + + err2 = attachOrDetachTag(tagHandler.TaggingService, tag, *securityGroup.CRN, action) + case irs.KEY: vmKeyPair, err := getRawKey(resIID, tagHandler.VpcService, tagHandler.Ctx) - if err != nil{ - log.Fatalf("Failed to Attach Tag: %v", err) + if err != nil { + err2 = errors.New(fmt.Sprintf("Failed to add tag. err = %s", err)) + break } - AttachTag(tagHandler.CredentialInfo.ApiKey, resIID, tag, *vmKeyPair.CRN) - case "VM": + + err2 = attachOrDetachTag(tagHandler.TaggingService, tag, *vmKeyPair.CRN, action) + case irs.VM: vm, err := getRawInstance(resIID, tagHandler.VpcService, tagHandler.Ctx) - if err != nil{ - log.Fatalf("Failed to Attach Tag: %v", err) + if err != nil { + err2 = errors.New(fmt.Sprintf("Failed to add tag. err = %s", err)) + break } - AttachTag(tagHandler.CredentialInfo.ApiKey, resIID, tag, *vm.CRN) - case "Disk": + + err2 = attachOrDetachTag(tagHandler.TaggingService, tag, *vm.CRN, action) + case irs.DISK: disk, err := getRawVolume(resIID, tagHandler.VpcService, tagHandler.Ctx) - if err != nil{ - log.Fatalf("Failed to Attach Tag: %v", err) + if err != nil { + err2 = errors.New(fmt.Sprintf("Failed to add tag. err = %s", err)) + break } - AttachTag(tagHandler.CredentialInfo.ApiKey, resIID, tag, *disk.CRN) - // case "MyImage": + + err2 = attachOrDetachTag(tagHandler.TaggingService, tag, *disk.CRN, action) + // case irs.MYIMAGE: // imageHandler := &IbmMyImageHandler{} // rawMyimage, err := imageHandler.GetMyImage(resIID) - // if err != nil { - // getErr := errors.New(fmt.Sprintf("Failed to Get NLB. err = %s", err.Error())) - // cblogger.Error(getErr.Error()) - // } - // AttachTag(tagHandler.CredentialInfo.ApiKey, resIID, tag, *rawMyimage.CRN) - case "NLB": + // if err != nil { + // err2 = errors.New(fmt.Sprintf("Failed to add tag. err = %s", err)) + // break + // } + // err2 = attachOrDetachTag(tagHandler.TaggingService, tag, *rawMyimage.CRN, action + case irs.NLB: nlbHandler := &IbmNLBHandler{} // or however you initialize IbmNLBHandler - rawNLB, err := nlbHandler.getRawNLBByName(resIID.NameId) - if err != nil { - getErr := errors.New(fmt.Sprintf("Failed to Get NLB. err = %s", err.Error())) - cblogger.Error(getErr.Error()) - } - AttachTag(tagHandler.CredentialInfo.ApiKey, resIID, tag, *rawNLB.CRN) + rawNLB, err := nlbHandler.getRawNLBByName(resIID.NameId) + if err != nil { + err2 = errors.New(fmt.Sprintf("Failed to add tag. err = %s", err)) + break + } + + err2 = attachOrDetachTag(tagHandler.TaggingService, tag, *rawNLB.CRN, action) + default: + return errors.New("invalid resource type") } - return irs.KeyValue{Key: tag.Key, Value: tag.Value}, nil + return err2 } -// RemoveTag implements resources.TagHandler. -func (tagHandler *IbmTagHandler) RemoveTag(resType irs.RSType, resIID irs.IID, tagName string) (bool, error) { - switch resType { - case "VPC": - vpc, err := GetRawVPC(resIID, tagHandler.VpcService, tagHandler.Ctx) - if err != nil{ - log.Fatalf("Failed to Attach Tag: %v", err) - } - DetachTag(tagHandler.CredentialInfo.ApiKey, resIID, tagName, *vpc.CRN) - case "Subnet": - vpc, err := GetRawVPC(resIID, tagHandler.VpcService, tagHandler.Ctx) - if err != nil{ - log.Fatalf("Failed to Attach Tag: %v", err) - } +func (tagHandler *IbmTagHandler) AddTag(resType irs.RSType, resIID irs.IID, tag irs.KeyValue) (irs.KeyValue, error) { + hiscallInfo := GetCallLogScheme(tagHandler.Region, call.TAG, resIID.NameId, "AddTag()") + start := call.Start() - subnet, err := getVPCRawSubnet(vpc, resIID, tagHandler.VpcService, tagHandler.Ctx) - if err != nil{ - log.Fatalf("Failed to Attach Tag: %v", err) - } - DetachTag(tagHandler.CredentialInfo.ApiKey, resIID, tagName, *subnet.CRN) - case "SecurityGroup": - securityGroup, err := getRawSecurityGroup(resIID, tagHandler.VpcService, tagHandler.Ctx) - if err != nil{ - log.Fatalf("Failed to Attach Tag: %v", err) - } - DetachTag(tagHandler.CredentialInfo.ApiKey, resIID, tagName, *securityGroup.CRN) - case "VMKeyPair": - vmKeyPair, err := getRawKey(resIID, tagHandler.VpcService, tagHandler.Ctx) - if err != nil{ - log.Fatalf("Failed to Attach Tag: %v", err) + tagFound, _ := getTagFromResource(tagHandler.SearchService, resType, resIID, tag.Key) + if tagFound.Key == tag.Key { + return tagFound, errors.New("tag with provided key is already exists") + } + + err := handleTagAddOrRemove(tagHandler, resType, resIID, tag, "add") + if err != nil { + getErr := errors.New(fmt.Sprintf("Failed to add a tag. err = %s", err)) + cblogger.Error(getErr.Error()) + LoggingError(hiscallInfo, getErr) + return irs.KeyValue{}, getErr + } + + LoggingInfo(hiscallInfo, start) + + return irs.KeyValue{Key: tag.Key, Value: tag.Value}, nil +} + +func (tagHandler *IbmTagHandler) ListTag(resType irs.RSType, resIID irs.IID) ([]irs.KeyValue, error) { + hiscallInfo := GetCallLogScheme(tagHandler.Region, call.TAG, resIID.NameId, "ListTag()") + start := call.Start() + + ibmType := rsTypeToIBMType(resType) + if ibmType == "" { + return []irs.KeyValue{}, errors.New("invalid resource type") + } + + searchOptions := tagHandler.SearchService.NewSearchOptions() + + var query string + + if resIID.NameId != "" { + query = fmt.Sprintf("type:%s AND name:%s", resType, resIID.NameId) + } else { + query = fmt.Sprintf("type:%s AND id:%s", resType, resIID.SystemId) + } + + searchOptions.SetQuery(query) + searchOptions.SearchCursor = nil + searchOptions.SetFields([]string{"name", "type", "crn", "tags"}) + searchOptions.SetLimit(100) + + var tagList []irs.KeyValue + + for { + scanResult, _, err := tagHandler.SearchService.Search(searchOptions) + if err != nil { + getErr := errors.New(fmt.Sprintf("Failed to list tag. err = %s", err)) + cblogger.Error(getErr.Error()) + LoggingError(hiscallInfo, getErr) + return tagList, err } - DetachTag(tagHandler.CredentialInfo.ApiKey, resIID, tagName, *vmKeyPair.CRN) - case "VM": - vm, err := getRawInstance(resIID, tagHandler.VpcService, tagHandler.Ctx) - if err != nil{ - log.Fatalf("Failed to Attach Tag: %v", err) + + if len(scanResult.Items) == 0 { + break } - DetachTag(tagHandler.CredentialInfo.ApiKey, resIID, tagName, *vm.CRN) - case "Disk": - disk, err := getRawVolume(resIID, tagHandler.VpcService, tagHandler.Ctx) - if err != nil{ - log.Fatalf("Failed to Attach Tag: %v", err) + + searchOptions.SearchCursor = scanResult.SearchCursor + + for _, item := range scanResult.Items { + tags, ok := item.GetProperty("tags").([]interface{}) + if !ok { + cblogger.Error("Tags are not in expected format") + continue + } + for _, tag := range tags { + tagStr, ok := tag.(string) + if !ok { + cblogger.Error("Tag is not a string") + continue + } + + parts := strings.SplitN(tagStr, ":", 2) + tagList = append(tagList, irs.KeyValue{ + Key: parts[0], + Value: parts[1], + }) + } } - DetachTag(tagHandler.CredentialInfo.ApiKey, resIID, tagName, *disk.CRN) - // case "MyImage": - // myImageHandler := &IbmMyImageHandler{} - // rawMyimage, err := myImageHandler.GetMyImage(resIID) - // if err != nil { - // getErr := errors.New(fmt.Sprintf("Failed to Get NLB. err = %s", err.Error())) - // cblogger.Error(getErr.Error()) - // } - // DetachTag(tagHandler.CredentialInfo.ApiKey, resIID, tagName, *rawMyimage.CRN) - case "NLB": - nlbHandler := &IbmNLBHandler{} // or however you initialize IbmNLBHandler - rawNLB, err := nlbHandler.getRawNLBByName(resIID.NameId) - if err != nil { - getErr := errors.New(fmt.Sprintf("Failed to Get NLB. err = %s", err.Error())) - cblogger.Error(getErr.Error()) - } - DetachTag(tagHandler.CredentialInfo.ApiKey, resIID, tagName, *rawNLB.CRN) } - return true, nil -} + LoggingInfo(hiscallInfo, start) -func AttachTag (apikey string, resIID irs.IID, tag irs.KeyValue, CRN string){ - // IBM Cloud API Key 설정 - authenticator := &core.IamAuthenticator{ - ApiKey: apikey, - } - - // GlobalTaggingV1 인스턴스 생성 - service, err := globalTaggingService.NewGlobalTaggingV1(&globalTaggingService.GlobalTaggingV1Options{ - Authenticator: authenticator, - }) - if err != nil { - fmt.Errorf("failed to create service: %w", err) - } - - resourceModel := globalTaggingService.Resource{ - ResourceID: &CRN, - } + return tagList, nil +} - attachTagOptions := service.NewAttachTagOptions( - []globalTaggingService.Resource{resourceModel}, - ) +func (tagHandler *IbmTagHandler) GetTag(resType irs.RSType, resIID irs.IID, key string) (irs.KeyValue, error) { + hiscallInfo := GetCallLogScheme(tagHandler.Region, call.TAG, resIID.NameId, "GetTag()") + start := call.Start() - tagName := "" - if tag.Value == "" { - tagName = tag.Key - } else { - tagName = tag.Key + ":" + tag.Value + tag, err := getTagFromResource(tagHandler.SearchService, resType, resIID, key) + if err != nil { + getErr := errors.New(fmt.Sprintf("Failed to get tag. err = %s", err)) + cblogger.Error(getErr.Error()) + LoggingError(hiscallInfo, getErr) + return irs.KeyValue{}, err } - attachTagOptions.SetTagNames([]string{tagName}) - attachTagOptions.SetTagType("user") + LoggingInfo(hiscallInfo, start) - tagResults, response, err := service.AttachTag(attachTagOptions) + return tag, nil +} + +func (tagHandler *IbmTagHandler) RemoveTag(resType irs.RSType, resIID irs.IID, key string) (bool, error) { + hiscallInfo := GetCallLogScheme(tagHandler.Region, call.TAG, resIID.NameId, "RemoveTag()") + start := call.Start() + + err := handleTagAddOrRemove(tagHandler, resType, resIID, irs.KeyValue{Key: key}, "remove") if err != nil { + getErr := errors.New(fmt.Sprintf("Failed to remove a tag. err = %s", err)) + cblogger.Error(getErr.Error()) + LoggingError(hiscallInfo, getErr) + return false, getErr } - // 응답 디버깅 - if response != nil { - fmt.Printf("Response status code: %d\n", response.StatusCode) - } + LoggingInfo(hiscallInfo, start) - b, _ := json.MarshalIndent(tagResults, "", " ") - fmt.Println(string(b)) + return true, nil } -func DetachTag (apikey string, resIID irs.IID, tagName string, CRN string){ - // IBM Cloud API Key 설정 - authenticator := &core.IamAuthenticator{ - ApiKey: apikey, - } +func (tagHandler *IbmTagHandler) FindTag(resType irs.RSType, keyword string) ([]*irs.TagInfo, error) { + hiscallInfo := GetCallLogScheme(tagHandler.Region, call.TAG, keyword, "FindTag()") + start := call.Start() - // GlobalTaggingV1 인스턴스 생성 - service, err := globalTaggingService.NewGlobalTaggingV1(&globalTaggingService.GlobalTaggingV1Options{ - Authenticator: authenticator, - }) - if err != nil { - fmt.Errorf("failed to delete service: %w", err) - } + ibmType := rsTypeToIBMType(resType) + if ibmType == "" { + return []*irs.TagInfo{}, errors.New("invalid resource type") + } - // Detach 진행 - resourceCRN := CRN - resourceModel := globalTaggingService.Resource{ - ResourceID: &resourceCRN, - } + searchOptions := tagHandler.SearchService.NewSearchOptions() - detachTagOptions := service.NewDetachTagOptions( - []globalTaggingService.Resource{resourceModel}, - ) + query := fmt.Sprintf("type:%s", ibmType) + searchOptions.SetQuery(query) + searchOptions.SearchCursor = nil + searchOptions.SetFields([]string{"name", "resource_id", "type", "crn", "tags"}) + searchOptions.SetLimit(100) - detachTagOptions.SetTagNames([]string{tagName}) - detachTagOptions.SetTagType("user") + var tagInfo []*irs.TagInfo - detachTagResults, response, err := service.DetachTag(detachTagOptions) + for { + scanResult, _, err := tagHandler.SearchService.Search(searchOptions) if err != nil { - log.Fatalf("Failed to delete service: %v", err) + getErr := errors.New(fmt.Sprintf("Failed to list tag. err = %s", err)) + cblogger.Error(getErr.Error()) + LoggingError(hiscallInfo, getErr) + return tagInfo, err } - b, _ := json.MarshalIndent(detachTagResults, "", " ") - fmt.Println(string(b)) - // Delete 진행 - deleteTagOptions := service.NewDeleteTagOptions(tagName) - deleteTagOptions.SetTagType("user") + if len(scanResult.Items) == 0 { + break + } - deleteTagResults, response, err := service.DeleteTag(deleteTagOptions) - if err != nil { - log.Fatalf("Failed to delete service: %v", err) + searchOptions.SearchCursor = scanResult.SearchCursor + + for _, item := range scanResult.Items { + var tagFound bool + + tags, ok := item.GetProperty("tags").([]interface{}) + if !ok { + cblogger.Error("Tags are not in expected format") + continue + } + for _, tag := range tags { + tagStr, ok := tag.(string) + if !ok { + cblogger.Errorf("Tag is not a string (%v)", tag) + continue + } + if strings.Contains(tagStr, keyword) { + tagFound = true + break + } + } + + if tagFound { + var tagKeyValue []irs.KeyValue + for _, tag := range tags { + tagStr, ok := tag.(string) + if !ok { + cblogger.Errorf("Tag is not a string (%v)", tag) + continue + } + parts := strings.SplitN(tagStr, ":", 2) + tagKeyValue = append(tagKeyValue, irs.KeyValue{ + Key: parts[0], + Value: parts[1], + }) + } + + rType, ok := item.GetProperty("type").(string) + if !ok { + cblogger.Error("type is not a string") + continue + } + rsType, err := ibmTypeToRSType(rType) + if err != nil { + cblogger.Error(err) + continue + } + + tagInfo = append(tagInfo, &irs.TagInfo{ + ResType: rsType, + ResIId: irs.IID{NameId: (item.GetProperty("name")).(string), SystemId: (item.GetProperty("resource_id").(string))}, + TagList: tagKeyValue, + KeyValueList: []irs.KeyValue{}, // reserved for optional usage + }) + } } + } - b, _ = json.MarshalIndent(deleteTagResults, "", " ") - fmt.Println(string(b)) + LoggingInfo(hiscallInfo, start) - // 응답 디버깅 - if response != nil { - fmt.Printf("Response status code: %d\n", response.StatusCode) - } -} \ No newline at end of file + return tagInfo, nil +} diff --git a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/VPCHandler.go b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/VPCHandler.go index fe1311182..acc39a360 100644 --- a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/VPCHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/VPCHandler.go @@ -615,6 +615,50 @@ func getVPCRawSubnets(vpc vpcv1.VPC, vpcService *vpcv1.VpcV1, ctx context.Contex return newSubnetInfos, nil } +func getRawSubnet(subnetIID irs.IID, vpcService *vpcv1.VpcV1, ctx context.Context) (vpcv1.Subnet, error) { + options := &vpcv1.ListSubnetsOptions{} + subnets, _, err := vpcService.ListSubnetsWithContext(ctx, options) + if err != nil { + return vpcv1.Subnet{}, err + } + var subnetFoundByName bool + var foundedSubnetByName vpcv1.Subnet + for { + if *subnets.TotalCount > 0 { + for _, subnet := range subnets.Subnets { + if subnetIID.SystemId != "" && *subnet.ID == subnetIID.SystemId { + return subnet, nil + } + if subnetIID.NameId == *subnet.Name { + if subnetFoundByName { + return vpcv1.Subnet{}, errors.New("found multiple subnets") + } + subnetFoundByName = true + foundedSubnetByName = subnet + } + } + } + nextstr, _ := getSubnetNextHref(subnets.Next) + if nextstr != "" { + options := &vpcv1.ListSubnetsOptions{ + Start: core.StringPtr(nextstr), + } + subnets, _, err = vpcService.ListSubnetsWithContext(ctx, options) + if err != nil { + break + } + } else { + break + } + } + + if subnetFoundByName { + return foundedSubnetByName, nil + } + + return vpcv1.Subnet{}, err +} + func getVPCRawSubnet(vpc vpcv1.VPC, subnetIID irs.IID, vpcService *vpcv1.VpcV1, ctx context.Context) (vpcv1.Subnet, error) { options := &vpcv1.ListSubnetsOptions{} subnets, _, err := vpcService.ListSubnetsWithContext(ctx, options) From c01cbb85bcdda5d4ce4cb84b946218817052ebab Mon Sep 17 00:00:00 2001 From: ish Date: Fri, 26 Jul 2024 18:41:25 +0900 Subject: [PATCH 23/32] IBM: Fix cluster creating issue --- .../drivers/ibmcloud-vpc/resources/ClusterHandler.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/ClusterHandler.go b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/ClusterHandler.go index 74323b623..9aff95abb 100644 --- a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/ClusterHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/ClusterHandler.go @@ -162,7 +162,7 @@ func (ic *IbmClusterHandler) CreateCluster(clusterReqInfo irs.ClusterInfo) (irs. if getRawVpcErr != nil { cblogger.Error(getRawVpcErr) LoggingError(hiscallInfo, getRawVpcErr) - ic.DeleteCluster(clusterReqInfo.IId) + _, _ = ic.DeleteCluster(clusterReqInfo.IId) return irs.ClusterInfo{}, errors.New(fmt.Sprintf("Failed to Create Cluster. err = %s", getRawVpcErr)) } @@ -1385,7 +1385,6 @@ func (ic *IbmClusterHandler) getWorkerPoolFromNodeGroupInfo(nodeGroupInfo irs.No ID: core.StringPtr(ic.Region.Zone), SubnetID: core.StringPtr(subnetId), }}, - OperatingSystem: core.StringPtr("UBUNTU_18_64"), } } From 5dd4322c967363f85d5b6d47fe7fd8f94110069d Mon Sep 17 00:00:00 2001 From: ish Date: Fri, 26 Jul 2024 18:41:46 +0900 Subject: [PATCH 24/32] IBM: Show cluster prices --- .../drivers/ibmcloud-vpc/resources/PriceInfoHandler.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/PriceInfoHandler.go b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/PriceInfoHandler.go index 4af88ce0b..5183e7209 100644 --- a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/PriceInfoHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/PriceInfoHandler.go @@ -326,8 +326,8 @@ func (priceInfoHandler *IbmPriceInfoHandler) ListProductFamily(regionName string mutex.Lock() for _, resource := range rsInfoTemp.Resources { - // Only accept name starts with 'is.' - if strings.HasPrefix(resource.Name, "is.") { + // Only accept name starts with 'is.' or find kubernetes + if strings.HasPrefix(resource.Name, "is.") || resource.Name == "containers-kubernetes" { for _, geo := range resource.GeoTags { if geo == regionName { kinds = append(kinds, resource.Name) From 5bd23c29632a47060dbcec98fe2ca6624f381286 Mon Sep 17 00:00:00 2001 From: ish Date: Fri, 26 Jul 2024 19:39:46 +0900 Subject: [PATCH 25/32] IBM: Fix security group setup issue while creating cluster --- .../ibmcloud-vpc/resources/ClusterHandler.go | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/ClusterHandler.go b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/ClusterHandler.go index 9aff95abb..7856d89d3 100644 --- a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/ClusterHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/ClusterHandler.go @@ -1413,15 +1413,29 @@ func (ic *IbmClusterHandler) initSecurityGroup(clusterReqInfo irs.ClusterInfo, c if getSgErr != nil { initSuccess = false ic.manageStatusTag(clusterCrn, SecurityGroupStatus, FAILED) - ic.DeleteCluster(clusterReqInfo.IId) + _, _ = ic.DeleteCluster(clusterReqInfo.IId) break } - _, sgUpdateErr := sgHandler.AddRules(defaultSgInfo.IId, sgInfo.SecurityRules) + var updateRules []irs.SecurityRuleInfo + for _, newRule := range *sgInfo.SecurityRules { + existCheck := false + for _, baseRule := range *defaultSgInfo.SecurityRules { + if equalsRule(newRule, baseRule) { + existCheck = true + break + } + } + if existCheck { + continue + } + updateRules = append(updateRules, newRule) + } + _, sgUpdateErr := sgHandler.AddRules(defaultSgInfo.IId, &updateRules) if sgUpdateErr != nil { initSuccess = false ic.manageStatusTag(clusterCrn, SecurityGroupStatus, FAILED) - ic.DeleteCluster(clusterReqInfo.IId) + _, _ = ic.DeleteCluster(clusterReqInfo.IId) break } } From 64f68aa42344cab2414467256f08e804d9ac940e Mon Sep 17 00:00:00 2001 From: ish Date: Fri, 26 Jul 2024 19:43:26 +0900 Subject: [PATCH 26/32] IBM: config: Update k8s version --- .../drivers/ibmcloud-vpc/main/conf/config.yaml.sample | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/main/conf/config.yaml.sample b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/main/conf/config.yaml.sample index 39c2f4865..e7bb05600 100644 --- a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/main/conf/config.yaml.sample +++ b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/main/conf/config.yaml.sample @@ -72,7 +72,7 @@ ibmvpc: cluster: IID: nameId: mycluster - version: "1.24.9" + version: "1.30.2" network: vpcIID: nameId: "cb-sp-container" @@ -113,5 +113,5 @@ ibmvpc: desiredNodeSize: 2 minNodeSize: 2 maxNodeSize: 3 - upgradeVersion: "1.25.5" + upgradeVersion: "1.30.2" From 3d38547ec9b255f55806d32266ae8a09aeb397d3 Mon Sep 17 00:00:00 2001 From: ish Date: Fri, 26 Jul 2024 21:06:55 +0900 Subject: [PATCH 27/32] IBM: Add cluster support to TagHandler --- .../connect/Ibm_CloudConnection.go | 1 + .../ibmcloud-vpc/resources/ClusterHandler.go | 36 +++++++++++ .../ibmcloud-vpc/resources/TagHandler.go | 60 ++++++++++++++++--- 3 files changed, 89 insertions(+), 8 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/connect/Ibm_CloudConnection.go b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/connect/Ibm_CloudConnection.go index 959c8b8af..5263d2dbf 100644 --- a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/connect/Ibm_CloudConnection.go +++ b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/connect/Ibm_CloudConnection.go @@ -182,6 +182,7 @@ func (cloudConn *IbmCloudConnection) CreateTagHandler() (irs.TagHandler, error) CredentialInfo: cloudConn.CredentialInfo, Region: cloudConn.Region, VpcService: cloudConn.VpcService, + ClusterService: cloudConn.ClusterService, Ctx: cloudConn.Ctx, TaggingService: cloudConn.TaggingService, SearchService: cloudConn.SearchService, diff --git a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/ClusterHandler.go b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/ClusterHandler.go index 7856d89d3..074299530 100644 --- a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/ClusterHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/ClusterHandler.go @@ -317,6 +317,42 @@ func (ic *IbmClusterHandler) ListCluster() ([]*irs.ClusterInfo, error) { return ret, nil } +func (ic *IbmClusterHandler) getRawCluster(clusterIID irs.IID) (kubernetesserviceapiv1.GetClusterDetailResponse, error) { + rawCluster := kubernetesserviceapiv1.GetClusterDetailResponse{} + + if clusterIID.NameId == "" && clusterIID.SystemId == "" { + return rawCluster, errors.New("Failed to Get Cluster. err = invalid IID") + } + + resourceGroupId, getResourceGroupIdErr := ic.getDefaultResourceGroupId() + if getResourceGroupIdErr != nil { + return rawCluster, errors.New(fmt.Sprintf("Failed to Get Cluster. err = %s", getResourceGroupIdErr)) + } + + var cluster string + if clusterIID.SystemId != "" { + cluster = clusterIID.SystemId + } else { + cluster = clusterIID.NameId + } + rawClusters, _, getClustersErr := ic.ClusterService.VpcGetClusterWithContext(ic.Ctx, &kubernetesserviceapiv1.VpcGetClusterOptions{ + Cluster: core.StringPtr(cluster), + XAuthResourceGroup: core.StringPtr(resourceGroupId), + ShowResources: core.StringPtr("true"), + }) + if getClustersErr != nil { + return rawCluster, errors.New(fmt.Sprintf("Failed to Get Cluster. err = %s", getClustersErr)) + } + + for _, rCluster := range *rawClusters { + if rCluster.Id == clusterIID.SystemId || rCluster.Name == clusterIID.NameId { + return rCluster, nil + } + } + + return rawCluster, errors.New("Failed to Get Cluster. err = cluster not found") +} + func (ic *IbmClusterHandler) GetCluster(clusterIID irs.IID) (irs.ClusterInfo, error) { hiscallInfo := GetCallLogScheme(ic.Region, call.CLUSTER, clusterIID.NameId, "GetCluster()") start := call.Start() diff --git a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/TagHandler.go b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/TagHandler.go index c74ca800c..90316d23d 100644 --- a/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/TagHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/resources/TagHandler.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" call "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/call-log" + "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/drivers/ibmcloud-vpc/utils/kubernetesserviceapiv1" "strings" "github.com/IBM/platform-services-go-sdk/globalsearchv2" @@ -18,6 +19,7 @@ type IbmTagHandler struct { Region idrv.RegionInfo CredentialInfo idrv.CredentialInfo VpcService *vpcv1.VpcV1 + ClusterService *kubernetesserviceapiv1.KubernetesServiceApiV1 Ctx context.Context TaggingService *globaltaggingv1.GlobalTaggingV1 SearchService *globalsearchv2.GlobalSearchV2 @@ -73,7 +75,7 @@ func rsTypeToIBMType(resType irs.RSType) string { case irs.MYIMAGE: return "snapshot" case irs.CLUSTER: - return "" + return "k8-cluster" case irs.NODEGROUP: return "instance-group" default: @@ -82,8 +84,6 @@ func rsTypeToIBMType(resType irs.RSType) string { } func ibmTypeToRSType(ibmType string) (irs.RSType, error) { - fmt.Println(ibmType) - switch ibmType { case "image": return irs.IMAGE, nil @@ -103,8 +103,8 @@ func ibmTypeToRSType(ibmType string) (irs.RSType, error) { return irs.DISK, nil case "snapshot": return irs.MYIMAGE, nil - //case "???": - // return irs.CLUSTER + case "k8-cluster": + return irs.CLUSTER, nil case "instance-group": return irs.NODEGROUP, nil default: @@ -303,6 +303,22 @@ func handleTagAddOrRemove(tagHandler *IbmTagHandler, resType irs.RSType, resIID } err2 = attachOrDetachTag(tagHandler.TaggingService, tag, *rawNLB.CRN, action) + case irs.CLUSTER: + clusterHandler := &IbmClusterHandler{ + CredentialInfo: tagHandler.CredentialInfo, + Region: tagHandler.Region, + Ctx: tagHandler.Ctx, + VpcService: tagHandler.VpcService, + ClusterService: tagHandler.ClusterService, + TaggingService: tagHandler.TaggingService, + } + rawCluster, err := clusterHandler.getRawCluster(resIID) + if err != nil { + err2 = errors.New(fmt.Sprintf("Failed to add tag. err = %s", err)) + break + } + + err2 = attachOrDetachTag(tagHandler.TaggingService, tag, rawCluster.Crn, action) default: return errors.New("invalid resource type") } @@ -346,9 +362,9 @@ func (tagHandler *IbmTagHandler) ListTag(resType irs.RSType, resIID irs.IID) ([] var query string if resIID.NameId != "" { - query = fmt.Sprintf("type:%s AND name:%s", resType, resIID.NameId) + query = fmt.Sprintf("type:%s AND name:%s", ibmType, resIID.NameId) } else { - query = fmt.Sprintf("type:%s AND id:%s", resType, resIID.SystemId) + query = fmt.Sprintf("type:%s AND id:%s", ibmType, resIID.SystemId) } searchOptions.SetQuery(query) @@ -514,9 +530,37 @@ func (tagHandler *IbmTagHandler) FindTag(resType irs.RSType, keyword string) ([] continue } + name, ok := item.GetProperty("name").(string) + if !ok { + cblogger.Error("name is not a string") + continue + } + resourceId, ok := item.GetProperty("resource_id").(string) + if !ok { + cblogger.Error("resource_id is not a string") + continue + } + + if rsType == irs.CLUSTER { + clusterHandler := &IbmClusterHandler{ + CredentialInfo: tagHandler.CredentialInfo, + Region: tagHandler.Region, + Ctx: tagHandler.Ctx, + VpcService: tagHandler.VpcService, + ClusterService: tagHandler.ClusterService, + TaggingService: tagHandler.TaggingService, + } + rawCluster, err := clusterHandler.getRawCluster(irs.IID{NameId: name}) + if err != nil { + cblogger.Error(err) + continue + } + resourceId = rawCluster.Id + } + tagInfo = append(tagInfo, &irs.TagInfo{ ResType: rsType, - ResIId: irs.IID{NameId: (item.GetProperty("name")).(string), SystemId: (item.GetProperty("resource_id").(string))}, + ResIId: irs.IID{NameId: name, SystemId: resourceId}, TagList: tagKeyValue, KeyValueList: []irs.KeyValue{}, // reserved for optional usage }) From 0e3d12a51e5e421fc6e94b199e9023f469e3c1a3 Mon Sep 17 00:00:00 2001 From: powerkimhub Date: Sat, 27 Jul 2024 14:36:29 +0900 Subject: [PATCH 28/32] List/Get VMStatus need to wait for https://github.com/cloud-barista/cb-spider/pull/1244#issuecomment-2253741979 --- api-runtime/common-runtime/VMManager.go | 73 +++++++++++++++++++------ 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/api-runtime/common-runtime/VMManager.go b/api-runtime/common-runtime/VMManager.go index f056655c1..bedd13173 100644 --- a/api-runtime/common-runtime/VMManager.go +++ b/api-runtime/common-runtime/VMManager.go @@ -1364,7 +1364,7 @@ func ListVMStatus(connectionName string, rsType string) ([]*cres.VMStatusInfo, e return infoList, nil } - // (2) get VMStatusInfo List with iidInoList + // (2) get VMStatusInfo List with iidInfoList infoList2 := []*cres.VMStatusInfo{} for _, iidInfo := range iidInfoList { @@ -1373,17 +1373,36 @@ func ListVMStatus(connectionName string, rsType string) ([]*cres.VMStatusInfo, e */ // 2. get CSP:VMStatus(SystemId) - statusInfo, err := handler.GetVMStatus(getDriverIID(cres.IID{NameId: iidInfo.NameId, SystemId: iidInfo.SystemId})) - if err != nil { - //vmSPLock.RUnlock(connectionName, iidInfo.IId.NameId) - if checkNotFoundError(err) { - cblog.Info(err) - continue + var statusInfo cres.VMStatus + driverIID := getDriverIID(cres.IID{NameId: iidInfo.NameId, SystemId: iidInfo.SystemId}) + + // need to wait for https://github.com/cloud-barista/cb-spider/pull/1244#issuecomment-2253741979 + waiter := NewWaiter(3, 60) // 3 seconds sleep, 60 seconds timeout + + for { + statusInfo, err = handler.GetVMStatus(driverIID) + if statusInfo == cres.NotExist { + err = fmt.Errorf("Not Found %s", driverIID.SystemId) + } + if err != nil { + if checkNotFoundError(err) { + statusInfo = cres.NotExist + break + } + cblog.Error(err) + return nil, err + } + + if statusInfo == cres.Creating || statusInfo == cres.Running || statusInfo == cres.Suspending || statusInfo == cres.Suspended || + statusInfo == cres.Resuming || statusInfo == cres.Rebooting || statusInfo == cres.Terminating || statusInfo == cres.Terminated || + statusInfo == cres.NotExist || statusInfo == cres.Failed { + break + } + + if !waiter.Wait() { + return nil, fmt.Errorf("Unable to provide current VM status for VM '%s'. Timeout after %v seconds", iidInfo.NameId, waiter.Timeout) } - cblog.Error(err) - return nil, err } - //vmSPLock.RUnlock(connectionName, iidInfo.IId.NameId) infoList2 = append(infoList2, &cres.VMStatusInfo{IId: getUserIID(cres.IID{NameId: iidInfo.NameId, SystemId: iidInfo.SystemId}), VmStatus: statusInfo}) } @@ -1433,14 +1452,34 @@ func GetVMStatus(connectionName string, rsType string, nameID string) (cres.VMSt return "", err } - // (2) get CSP:VMStatus(SystemId) - info, err := handler.GetVMStatus(getDriverIID(cres.IID{NameId: iidInfo.NameId, SystemId: iidInfo.SystemId})) - if err != nil { - cblog.Error(err) - return "", err - } + driverIID := getDriverIID(cres.IID{NameId: iidInfo.NameId, SystemId: iidInfo.SystemId}) - return info, nil + // need to wait for https://github.com/cloud-barista/cb-spider/pull/1244#issuecomment-2253741979 + waiter := NewWaiter(3, 60) // 3 seconds sleep, 60 seconds timeout + + for { + info, err := handler.GetVMStatus(driverIID) + if info == cres.NotExist { + err = fmt.Errorf("Not Found %s", driverIID.SystemId) + } + if err != nil { + if checkNotFoundError(err) { + return "", err + } + cblog.Error(err) + return "", err + } + + if info == cres.Creating || info == cres.Running || info == cres.Suspending || info == cres.Suspended || + info == cres.Resuming || info == cres.Rebooting || info == cres.Terminating || info == cres.Terminated || + info == cres.NotExist || info == cres.Failed { + return info, nil + } + + if !waiter.Wait() { + return "", fmt.Errorf("Unable to provide current VM status for VM '%s'. Timeout after %v seconds", nameID, waiter.Timeout) + } + } } // (1) get IID(NameId) From de0369288dfadc35633d3162617bd77152f6f41b Mon Sep 17 00:00:00 2001 From: powerkimhub Date: Sat, 27 Jul 2024 14:37:10 +0900 Subject: [PATCH 29/32] Update the version of Tencent SDK --- go.mod | 2 +- go.sum | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 633b59e51..1826cc94a 100644 --- a/go.mod +++ b/go.mod @@ -74,6 +74,7 @@ require ( github.com/labstack/echo/v4 v4.9.0 github.com/tencentcloud/tencentcloud-sdk-go-intl-en v3.0.531+incompatible github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs v1.0.492 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tag v1.0.964 golang.org/x/mod v0.18.0 k8s.io/api v0.22.5 k8s.io/apimachinery v0.22.5 @@ -97,7 +98,6 @@ require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/mattn/go-sqlite3 v1.14.22 // indirect - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tag v1.0.964 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/tjfoc/gmsm v1.4.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect diff --git a/go.sum b/go.sum index d08ee0de5..256b4bfe5 100644 --- a/go.sum +++ b/go.sum @@ -709,7 +709,6 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.415 h1:ylKa86l github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.415/go.mod h1:XswWFMZ7ekTOWvZlUXr7I21pKyLuRAyZGgR5fMDTCyM= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.415/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.492/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.493 h1:iROpofiufr+AiHdF5Vl9FlD1MNo11T5qe+s4q0pLTVo= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.493/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.964 h1:ET3EulYQvWrdD5FNwOP+196w5Vbniy/uRGucM5ILExQ= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.964/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= From 5fc8fd8fa3e0e543bbd31d8c56318bca52594dfd Mon Sep 17 00:00:00 2001 From: powerkimhub Date: Sat, 27 Jul 2024 15:27:53 +0900 Subject: [PATCH 30/32] Change log messages with english --- .../cloud-driver/drivers/alibaba/resources/VMHandler.go | 2 +- .../cloud-driver/drivers/aws/resources/VMHandler.go | 2 +- .../cloud-driver/drivers/gcp/resources/VMHandler.go | 2 +- .../cloud-driver/drivers/tencent/resources/VMHandler.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/alibaba/resources/VMHandler.go b/cloud-control-manager/cloud-driver/drivers/alibaba/resources/VMHandler.go index 8a7a6b24c..55d47b4c3 100644 --- a/cloud-control-manager/cloud-driver/drivers/alibaba/resources/VMHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/alibaba/resources/VMHandler.go @@ -1122,7 +1122,7 @@ func (vmHandler *AlibabaVMHandler) ConvertVMStatusString(vmStatus string) (irs.V cblogger.Errorf("Cannot find mapping information matching vmStatus [%s].", vmStatus) return irs.VMStatus("Failed"), errors.New("Cannot find CB VM status information matching " + vmStatus) } - cblogger.Infof("VM 상태 치환 : [%s] ==> [%s]", vmStatus, resultStatus) + cblogger.Infof("Replace VMStatus : [%s] ==> [%s]", vmStatus, resultStatus) return irs.VMStatus(resultStatus), nil } diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/VMHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/VMHandler.go index 152ec5752..f681276d3 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/VMHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/VMHandler.go @@ -1495,7 +1495,7 @@ func ConvertVMStatusString(vmStatus string) (irs.VMStatus, error) { cblogger.Errorf("No mapping information found matching vmStatus [%s", vmStatus) return irs.VMStatus("Failed"), errors.New("Cannot find status information that matches " + vmStatus) } - cblogger.Infof("VM 상태 치환 : [%s] ==> [%s]", vmStatus, resultStatus) + cblogger.Infof("VReplace VMStatus : [%s] ==> [%s]", vmStatus, resultStatus) return irs.VMStatus(resultStatus), nil } diff --git a/cloud-control-manager/cloud-driver/drivers/gcp/resources/VMHandler.go b/cloud-control-manager/cloud-driver/drivers/gcp/resources/VMHandler.go index 690fb4afd..daa44f9db 100644 --- a/cloud-control-manager/cloud-driver/drivers/gcp/resources/VMHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/gcp/resources/VMHandler.go @@ -878,7 +878,7 @@ func ConvertVMStatusString(vmStatus string) (irs.VMStatus, error) { cblogger.Errorf("Couldn't find mapping information matching vmStatus [%s].", vmStatus) return irs.VMStatus("Failed"), errors.New("Couldn't find CB VM status information matching vmStatus " + vmStatus) } - cblogger.Infof("VM 상태 치환 : [%s] ==> [%s]", vmStatus, resultStatus) + cblogger.Infof("Replace VMStatus : [%s] ==> [%s]", vmStatus, resultStatus) return irs.VMStatus(resultStatus), nil } diff --git a/cloud-control-manager/cloud-driver/drivers/tencent/resources/VMHandler.go b/cloud-control-manager/cloud-driver/drivers/tencent/resources/VMHandler.go index 57ab1765e..0a1ef59bd 100644 --- a/cloud-control-manager/cloud-driver/drivers/tencent/resources/VMHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/tencent/resources/VMHandler.go @@ -980,7 +980,7 @@ func ConvertVMStatusString(vmStatus string) (irs.VMStatus, error) { cblogger.Debugf("Mapping information matching vmStatus [%s] not found.", vmStatus) return irs.VMStatus("Failed"), errors.New("Cannot find CB VM status information matching " + vmStatus) } - cblogger.Infof("VM 상태 치환 : [%s] ==> [%s]", vmStatus, resultStatus) + cblogger.Infof("Replace VMStatus : [%s] ==> [%s]", vmStatus, resultStatus) return irs.VMStatus(resultStatus), nil } From 45e091f277215e50677176c3724462d80d7e8d70 Mon Sep 17 00:00:00 2001 From: powerkimhub Date: Sun, 28 Jul 2024 20:33:20 +0900 Subject: [PATCH 31/32] Tunning the left menu page --- .../rest-runtime/admin-web/html/left_menu.html | 16 +++++++++++++--- .../rest-runtime/admin-web/html/main.html | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/api-runtime/rest-runtime/admin-web/html/left_menu.html b/api-runtime/rest-runtime/admin-web/html/left_menu.html index 58e7f62fc..02e047714 100644 --- a/api-runtime/rest-runtime/admin-web/html/left_menu.html +++ b/api-runtime/rest-runtime/admin-web/html/left_menu.html @@ -4,7 +4,7 @@