diff --git a/cloud-control-manager/cloud-driver/drivers/ncp/README.md b/cloud-control-manager/cloud-driver/drivers/ncp/README.md
index 4b2015998..16cc222d8 100644
--- a/cloud-control-manager/cloud-driver/drivers/ncp/README.md
+++ b/cloud-control-manager/cloud-driver/drivers/ncp/README.md
@@ -88,20 +88,25 @@ $CBSPIDER_ROOT/cloud-control-manager/cloud-driver/drivers/ncp/main/
- 사용자가 keyPair 생성시 생성되는 private key를 local에 저장해놓고, 그 private key를 이용해 'cb-user' 계정으로 SSH를 이용해 로그인하는 방법을 제공함.
- - Private ket 파일을 이용한 VM 접속 방법
+ - Private key 파일을 이용한 Linux 계열 VM 접속 방법 (on CLI)
```
ssh -i /private_key_경로/private_key_파일명(~~.pem) cb-user@VM의_public_ip
```
+ O Cloud-Barista NCP driver를 이용해 생성된 VM에 로그인하는 방법(Windows 계열 guest OS 경우)
- (참고) NCP CSP에서 제공하는 VM 접속 방법
+ - 'Administrator' 계정으로 VM 생성시 사용자가 지정한 password로 로그인함.
- - VM 생성 후, NCP console에서 사용자가 생성한 private key를 이용해 해당 VM의 root 비밀번호를 알아내어 SSH를 이용해 root 계정과 비밀번호로 로그인함.
+
- O Cloud-Barista NCP driver를 이용해 생성된 VM에 로그인하는 방법(Windows 계열 guest OS 경우)
+ (참고-1) NCP CSP에서 기본적으로 제공하는 VM 접속 방법
+
+ - VM 생성 후, 사용자가 생성한 private key를 이용해 NCP console에서 해당 VM의 root 비밀번호를 알아내어 SSH를 이용해 root 계정과 비밀번호로 로그인함.
- - 'Administrator' 계정으로 VM 생성시 지정한 사용자가 password 로그인함.
+ (참고-2) NCP CSP 콘솔에서 key pair 목록 확인 방법
+
+ - Sever 메뉴 > Sever > 상단의 '서버 관리 및 설정 변경' > '인증키 관리' 선택
@@ -134,4 +139,7 @@ ssh -i /private_key_경로/private_key_파일명(~~.pem) cb-user@VM의_public_ip
- 단, NCP driver나 CB-Spider API를 이용해 NCP VM 반납시에는 VM 반납 후 자동으로 public IP까지 반납됨.
+
+ O NCP Classic은 클라우드 자원들중 VM 기준으로만 tag 생성이 가능함.
+
O NCP 정책상, VM이 생성된 후 한번 정지시킨 상태에서 연속으로 최대 90일, 12개월 누적 180일을 초과하여 정지할 수 없으며, 해당 기간을 초과할 경우 반납(Terminate)하도록 안내하고 있음.
diff --git a/cloud-control-manager/cloud-driver/drivers/ncp/connect/NcpCloudConnection.go b/cloud-control-manager/cloud-driver/drivers/ncp/connect/NcpCloudConnection.go
index d13bc3698..3541f4176 100644
--- a/cloud-control-manager/cloud-driver/drivers/ncp/connect/NcpCloudConnection.go
+++ b/cloud-control-manager/cloud-driver/drivers/ncp/connect/NcpCloudConnection.go
@@ -135,7 +135,10 @@ func (cloudConn *NcpCloudConnection) CreatePriceInfoHandler() (irs.PriceInfoHand
}
func (cloudConn *NcpCloudConnection) CreateTagHandler() (irs.TagHandler, error) {
- return nil, fmt.Errorf("NCP Cloud Driver does not support CreateTagHandler() yet.")
+ cblogger.Info("NCP Cloud Driver: called CreateTagHandler()!")
+
+ tagHandler := ncprs.NcpTagHandler{cloudConn.CredentialInfo, cloudConn.RegionInfo, cloudConn.VmClient}
+ return &tagHandler, nil
}
func (cloudConn *NcpCloudConnection) IsConnected() (bool, error) {
diff --git a/cloud-control-manager/cloud-driver/drivers/ncp/main/Test_TagHandler.go b/cloud-control-manager/cloud-driver/drivers/ncp/main/Test_TagHandler.go
new file mode 100644
index 000000000..d4db1674a
--- /dev/null
+++ b/cloud-control-manager/cloud-driver/drivers/ncp/main/Test_TagHandler.go
@@ -0,0 +1,243 @@
+// Proof of Concepts of CB-Spider.
+// The CB-Spider is a sub-Framework of the Cloud-Barista Multi-Cloud Project.
+// The CB-Spider Mission is to connect all the clouds with a single interface.
+//
+// * Cloud-Barista: https://github.com/cloud-barista
+//
+// This is a Cloud Driver Tester Example.
+//
+// by ETRI, 2024.07.
+
+package main
+
+import (
+ "os"
+ "errors"
+ "fmt"
+ // "bufio"
+ // "strings"
+ "github.com/davecgh/go-spew/spew"
+ "github.com/sirupsen/logrus"
+ "gopkg.in/yaml.v3"
+
+ 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"
+ cblog "github.com/cloud-barista/cb-log"
+
+ // ncpdrv "github.com/cloud-barista/ncp/ncp" // For local test
+ ncpdrv "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 Resource Test")
+ cblog.SetLevel("info")
+}
+
+func handleTag() {
+ cblogger.Debug("Start Disk Resource Test")
+
+ resourceHandler, err := getResourceHandler("Tag")
+ if err != nil {
+ cblogger.Error(err)
+ return
+ }
+ tagHandler := resourceHandler.(irs.TagHandler)
+ //config := readConfigFile()
+
+ for {
+ fmt.Println("\n============================================================================================")
+ fmt.Println("[ TagHandler Test ]")
+ cblogger.Info("1. ListTag()")
+ cblogger.Info("2. GetTag()")
+ cblogger.Info("3. AddTag()")
+ cblogger.Info("4. RemoveTag()")
+ cblogger.Info("5. FindTag()")
+ cblogger.Info("0. Exit")
+ fmt.Println("\n Select a number above!! : ")
+ fmt.Println("============================================================================================")
+
+ var commandNum int
+
+ rsType := irs.RSType(irs.VM)
+
+ rsIId := irs.IID{
+ NameId: "MyVM-1",
+ SystemId: "25453063",
+ }
+
+ tagKV := irs.KeyValue{
+ Key: "VPCNameTest",
+ Value: "NCP-myVPC-000001",
+ }
+
+ tagKey := "VPCNameTest"
+
+ keyword := "VPC"
+
+ inputCnt, err := fmt.Scan(&commandNum)
+ if err != nil {
+ panic(err)
+ }
+
+ if inputCnt == 1 {
+ switch commandNum {
+ case 0:
+ return
+ case 1:
+ cblogger.Info("Start ListTag() ...")
+ if tagList, err := tagHandler.ListTag(rsType, rsIId); err != nil {
+ cblogger.Error(err)
+ } else {
+ spew.Dump(tagList)
+ }
+ cblogger.Info("Finish ListTag()")
+ case 2:
+ cblogger.Info("Start GetTag() ...")
+ if tagKeyValue, err := tagHandler.GetTag(rsType, rsIId, tagKey); err != nil {
+ cblogger.Error(err)
+ } else {
+ spew.Dump(tagKeyValue)
+ }
+ cblogger.Info("Finish GetTag()")
+ case 3:
+ cblogger.Info("Start AddTag() ...")
+ if tagKeyValue, err := tagHandler.AddTag(rsType, rsIId, tagKV); err != nil {
+ cblogger.Error(err)
+ } else {
+ spew.Dump(tagKeyValue)
+ }
+ cblogger.Info("Finish AddTag()")
+ case 4:
+ cblogger.Info("Start RemoveTag() ...")
+ if tagKeyValue, err := tagHandler.RemoveTag(rsType, rsIId, tagKey); err != nil {
+ cblogger.Error(err)
+ } else {
+ spew.Dump(tagKeyValue)
+ }
+ cblogger.Info("Finish RemoveTag()")
+ case 5:
+ cblogger.Info("Start FindTag() ...")
+ if tagKeyValue, err := tagHandler.FindTag(rsType, keyword); err != nil {
+ cblogger.Error(err)
+ } else {
+ spew.Dump(tagKeyValue)
+ }
+ cblogger.Info("Finish FindTag()")
+ }
+ }
+ }
+}
+
+func testErr() error {
+
+ return errors.New("")
+}
+
+func main() {
+ cblogger.Info("NCP Resource Test")
+ handleTag()
+}
+
+//handlerType : resources폴더의 xxxHandler.go에서 Handler이전까지의 문자열
+//(예) ImageHandler.go -> "Image"
+func getResourceHandler(handlerType string) (interface{}, error) {
+ var cloudDriver idrv.CloudDriver
+ cloudDriver = new(ncpdrv.NcpDriver)
+
+ config := readConfigFile()
+ connectionInfo := idrv.ConnectionInfo{
+ CredentialInfo: idrv.CredentialInfo{
+ ClientId: config.Ncp.NcpAccessKeyID,
+ ClientSecret: config.Ncp.NcpSecretKey,
+ },
+ RegionInfo: idrv.RegionInfo{
+ Region: config.Ncp.Region,
+ Zone: config.Ncp.Zone,
+ },
+ }
+
+ cloudConnection, errCon := cloudDriver.ConnectCloud(connectionInfo)
+ if errCon != nil {
+ return nil, errCon
+ }
+
+ var resourceHandler interface{}
+ var err error
+
+ switch handlerType {
+ case "Image":
+ resourceHandler, err = cloudConnection.CreateImageHandler()
+ case "Security":
+ resourceHandler, err = cloudConnection.CreateSecurityHandler()
+ case "VNetwork":
+ resourceHandler, err = cloudConnection.CreateVPCHandler()
+ case "VM":
+ resourceHandler, err = cloudConnection.CreateVMHandler()
+ case "VMSpec":
+ resourceHandler, err = cloudConnection.CreateVMSpecHandler()
+ case "VPC":
+ resourceHandler, err = cloudConnection.CreateVPCHandler()
+ case "Disk":
+ resourceHandler, err = cloudConnection.CreateDiskHandler()
+ case "Tag":
+ resourceHandler, err = cloudConnection.CreateTagHandler()
+ }
+
+ if err != nil {
+ return nil, err
+ }
+ return resourceHandler, nil
+}
+
+type Config struct {
+ Ncp struct {
+ NcpAccessKeyID string `yaml:"ncp_access_key_id"`
+ NcpSecretKey string `yaml:"ncp_secret_key"`
+ Region string `yaml:"region"`
+ Zone string `yaml:"zone"`
+
+ ImageID string `yaml:"image_id"`
+
+ VmID string `yaml:"ncp_instance_id"`
+ BaseName string `yaml:"base_name"`
+ InstanceType string `yaml:"instance_type"`
+ KeyName string `yaml:"key_name"`
+ MinCount int64 `yaml:"min_count"`
+ MaxCount int64 `yaml:"max_count"`
+
+ SubnetID string `yaml:"subnet_id"`
+ SecurityGroupID string `yaml:"security_group_id"`
+
+ PublicIP string `yaml:"public_ip"`
+ } `yaml:"ncp"`
+}
+
+func readConfigFile() Config {
+ // # Set Environment Value of Project Root Path
+ // goPath := os.Getenv("GOPATH")
+ // rootPath := goPath + "/src/github.com/cloud-barista/ncp/ncp/main"
+ // cblogger.Debugf("Test Config file : [%]", rootPath+"/config/config.yaml")
+ rootPath := os.Getenv("CBSPIDER_ROOT")
+ configPath := rootPath + "/cloud-control-manager/cloud-driver/drivers/ncp/main/config/config.yaml"
+ cblogger.Debugf("Test Config file : [%s]", configPath)
+
+ data, err := os.ReadFile(configPath)
+ if err != nil {
+ panic(err)
+ }
+
+ var config Config
+ err = yaml.Unmarshal(data, &config)
+ if err != nil {
+ panic(err)
+ }
+ cblogger.Info("ConfigFile Loaded ...")
+
+ // Just for test
+ cblogger.Debug(config.Ncp.NcpAccessKeyID, " ", config.Ncp.Region)
+
+ return config
+}
diff --git a/cloud-control-manager/cloud-driver/drivers/ncp/resources/TagHandler.go b/cloud-control-manager/cloud-driver/drivers/ncp/resources/TagHandler.go
new file mode 100644
index 000000000..3bb8f0c7c
--- /dev/null
+++ b/cloud-control-manager/cloud-driver/drivers/ncp/resources/TagHandler.go
@@ -0,0 +1,216 @@
+package resources
+
+import (
+ "fmt"
+ "strings"
+
+ ncloud "github.com/NaverCloudPlatform/ncloud-sdk-go-v2/ncloud"
+ server "github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/server"
+
+ 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 NcpTagHandler struct {
+ CredentialInfo idrv.CredentialInfo
+ RegionInfo idrv.RegionInfo
+ VMClient *server.APIClient
+}
+
+func (tagHandler *NcpTagHandler) AddTag(resType irs.RSType, resIID irs.IID, tag irs.KeyValue) (irs.KeyValue, error) {
+ cblogger.Info("NCP Classic Cloud driver: called AddTag()!!")
+
+ if resType != irs.VM {
+ newErr := fmt.Errorf("Only 'VM' type are supported as a resource type to add a Tag on NCP Classic!!")
+ cblogger.Error(newErr.Error())
+ return irs.KeyValue{}, newErr
+ }
+
+ if strings.EqualFold(resIID.SystemId, "") {
+ newErr := fmt.Errorf("Invalid Resource SystemId")
+ cblogger.Error(newErr.Error())
+ return irs.KeyValue{}, newErr
+ }
+
+ _, err := tagHandler.createVMTag(&resIID.SystemId, tag)
+ if err != nil {
+ newErr := fmt.Errorf("Failed to Add New Tag : [%v]", err)
+ cblogger.Error(newErr.Error())
+ return irs.KeyValue{}, newErr
+ }
+
+ tagKV, err := tagHandler.GetTag(resType, resIID, tag.Key)
+ if err != nil {
+ newErr := fmt.Errorf("Failed to Get the Tag Info : [%v]", err)
+ cblogger.Error(newErr.Error())
+ return irs.KeyValue{}, newErr
+ }
+ return tagKV, nil
+}
+
+func (tagHandler *NcpTagHandler) ListTag(resType irs.RSType, resIID irs.IID) ([]irs.KeyValue, error) {
+ cblogger.Info("NCP Classic Cloud driver: called ListTag()!!")
+
+ return nil, fmt.Errorf("NCP Cloud Driver does not support ListTag yet.")
+}
+
+func (tagHandler *NcpTagHandler) GetTag(resType irs.RSType, resIID irs.IID, key string) (irs.KeyValue, error) {
+ cblogger.Info("NCP Classic Cloud driver: called GetTag()!")
+
+ if resType != irs.VM {
+ newErr := fmt.Errorf("Only 'VM' type are supported as a resource type to add a Tag on NCP Classic!!")
+ cblogger.Error(newErr.Error())
+ return irs.KeyValue{}, newErr
+ }
+
+ if strings.EqualFold(resIID.SystemId, "") {
+ newErr := fmt.Errorf("Invalid Resource SystemId")
+ cblogger.Error(newErr.Error())
+ return irs.KeyValue{}, newErr
+ }
+
+ tagValue, err := tagHandler.getVMTagValue(&resIID.SystemId, key)
+ if err != nil {
+ newErr := fmt.Errorf("Failed to Get the Tag Value with the Key : [%v]", err)
+ cblogger.Error(newErr.Error())
+ return irs.KeyValue{}, newErr
+ }
+
+ tagKV := irs.KeyValue{
+ Key: key,
+ Value: tagValue,
+ }
+ return tagKV, nil
+}
+
+func (tagHandler *NcpTagHandler) RemoveTag(resType irs.RSType, resIID irs.IID, key string) (bool, error) {
+ cblogger.Info("NCP Classic Cloud driver: called RemoveTag()!")
+
+ if resType != irs.VM {
+ newErr := fmt.Errorf("Only 'VM' type are supported as a resource type to add a Tag on NCP Classic!!")
+ cblogger.Error(newErr.Error())
+ return false, newErr
+ }
+
+ _, err := tagHandler.GetTag(resType, resIID, key)
+ if err != nil {
+ newErr := fmt.Errorf("The Tag with the Key does not exist [%v]", err)
+ cblogger.Error(newErr.Error())
+ return false, newErr
+ }
+
+ _, delErr := tagHandler.deleteVMTag(&resIID.SystemId, key)
+ if delErr != nil {
+ newErr := fmt.Errorf("Failed to Remove the Tag with the Key : [%v]", delErr)
+ cblogger.Error(newErr.Error())
+ return false, newErr
+ }
+
+ return true, nil
+}
+
+func (tagHandler *NcpTagHandler) FindTag(resType irs.RSType, keyword string) ([]*irs.TagInfo, error) {
+ cblogger.Info("NCP Classic Cloud driver: called FindTag()!")
+
+ if resType != irs.VM {
+ newErr := fmt.Errorf("Only 'VM' type are supported as a resource type to add a Tag on NCP Classic!!")
+ cblogger.Error(newErr.Error())
+ return nil, newErr
+ }
+
+ return nil, fmt.Errorf("NCP Cloud Driver does not support FindTag yet.")
+}
+
+func (tagHandler *NcpTagHandler) createVMTag(vmID *string, tag irs.KeyValue) (bool, error) {
+ cblogger.Info("NCP Classic Cloud driver: called createVMTag()!")
+
+ var instanceNos []*string
+ var instanceTags []*server.InstanceTagParameter
+
+ instanceNos = append(instanceNos, vmID)
+
+ instanceTags = []*server.InstanceTagParameter {
+ {
+ TagKey: ncloud.String(tag.Key),
+ TagValue: ncloud.String(tag.Value),
+ },
+ }
+ tagReq := server.CreateInstanceTagsRequest{
+ InstanceNoList: instanceNos,
+ InstanceTagList: instanceTags,
+ }
+ tagResult, err := tagHandler.VMClient.V2Api.CreateInstanceTags(&tagReq)
+ if err != nil {
+ newErr := fmt.Errorf("Failed to Create the Tag on the VM : [%v]", err)
+ cblogger.Error(newErr.Error())
+ return false, newErr
+ } else {
+ cblogger.Infof("Tag Creation Result : [%s]", *tagResult.ReturnMessage)
+ }
+
+ return true, nil
+}
+
+func (tagHandler *NcpTagHandler) getVMTagValue(vmID *string, key string) (string, error) {
+ cblogger.Info("NCP Classic Cloud driver: called getVMTagValue()!")
+
+ var instanceNos []*string
+ var tagValue string
+ instanceNos = append(instanceNos, vmID)
+
+ tagReq := server.GetInstanceTagListRequest{InstanceNoList: instanceNos}
+ tagListResult, err := tagHandler.VMClient.V2Api.GetInstanceTagList(&tagReq)
+ if err != nil {
+ newErr := fmt.Errorf("Failed to Get VM Tag List from the VM : [%v]", err)
+ cblogger.Error(newErr.Error())
+ return "", newErr
+ }
+ if len(tagListResult.InstanceTagList) < 1 {
+ newErr := fmt.Errorf("Failed to Find Any Tag with the VM SystemID!!")
+ cblogger.Error(newErr.Error())
+ return "", newErr
+ } else {
+ cblogger.Infof("Tag Info Listing Result : [%s]", *tagListResult.ReturnMessage)
+ }
+
+ for _, curTag := range tagListResult.InstanceTagList {
+ if strings.EqualFold(ncloud.StringValue(curTag.TagKey), key) {
+ tagValue = ncloud.StringValue(curTag.TagValue)
+ }
+ }
+ if len(tagValue) < 1 {
+ newErr := fmt.Errorf("Failed to Get the Tag Value with the Key!!")
+ cblogger.Error(newErr.Error())
+ return "", newErr
+ }
+ return tagValue, nil
+}
+
+func (tagHandler *NcpTagHandler) deleteVMTag(vmID *string, key string) (bool, error) {
+ cblogger.Info("NCP Classic Cloud driver: called deleteVMTag()!")
+
+ var instanceNos []*string
+ var instanceTags []*server.InstanceTagParameter
+
+ instanceNos = append(instanceNos, vmID)
+
+ instanceTags = []*server.InstanceTagParameter {
+ {
+ TagKey: ncloud.String(key),
+ },
+ }
+ tagReq := server.DeleteInstanceTagsRequest {
+ InstanceNoList: instanceNos,
+ InstanceTagList: instanceTags,
+ }
+ tagResult, err := tagHandler.VMClient.V2Api.DeleteInstanceTags(&tagReq)
+ if err != nil {
+ newErr := fmt.Errorf("Failed to Delete the Tag with the Key on the VM : [%v]", err)
+ cblogger.Error(newErr.Error())
+ return false, newErr
+ } else {
+ cblogger.Infof("Tag Deletion Result : [%s]", *tagResult.ReturnMessage)
+ }
+
+ return true, nil
+}
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 89aa7019d..433dd0524 100644
--- a/cloud-control-manager/cloud-driver/drivers/ncp/resources/VMHandler.go
+++ b/cloud-control-manager/cloud-driver/drivers/ncp/resources/VMHandler.go
@@ -82,7 +82,7 @@ func (vmHandler *NcpVMHandler) StartVM(vmReqInfo irs.VMReqInfo) (irs.VMInfo, err
// Check whether the VM name exists. Search by instanceName converted to lowercase
vmId, err := vmHandler.GetVmIdByName(instanceName)
if err != nil {
- cblogger.Error("The VM with the name is not exists : " + instanceName)
+ cblogger.Debug("The VM with the name does not exists : " + instanceName)
// return irs.VMInfo{}, err //Caution!!
}
if vmId != "" {