From 8e1a48b142f075b3a6e73746600326432de99e3e Mon Sep 17 00:00:00 2001 From: innodreamer Date: Mon, 30 Sep 2024 18:39:53 +0900 Subject: [PATCH] [KT Classic/VPC] Apply CreateTime to VPC/SG info --- .../ktcloud/resources/CommonKtCloudFunc.go | 51 +++++++++- .../ktcloud/resources/SecurityHandler.go | 94 +++++++++++------- .../drivers/ktcloud/resources/VPCHandler.go | 94 +++++++++++++----- .../ktcloudvpc/resources/CommonKTCloudFunc.go | 6 ++ .../ktcloudvpc/resources/SecurityHandler.go | 96 ++++++++++++------- 5 files changed, 245 insertions(+), 96 deletions(-) diff --git a/cloud-control-manager/cloud-driver/drivers/ktcloud/resources/CommonKtCloudFunc.go b/cloud-control-manager/cloud-driver/drivers/ktcloud/resources/CommonKtCloudFunc.go index d0323484e..2e2ca57ff 100644 --- a/cloud-control-manager/cloud-driver/drivers/ktcloud/resources/CommonKtCloudFunc.go +++ b/cloud-control-manager/cloud-driver/drivers/ktcloud/resources/CommonKtCloudFunc.go @@ -16,10 +16,14 @@ import ( "sync" "time" "os" + "strings" // "github.com/davecgh/go-spew/spew" "github.com/sirupsen/logrus" - cblog "github.com/cloud-barista/cb-log" + ktsdk "github.com/cloud-barista/ktcloud-sdk-go" + + cblog "github.com/cloud-barista/cb-log" + idrv "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces" call "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/call-log" ) @@ -129,3 +133,48 @@ func convertTimeFormat(inputTime string) (time.Time, error) { } return parsedTime, nil } + +func createClient(connectionInfo idrv.ConnectionInfo) (*ktsdk.KtCloudClient, error) { + cblogger.Info("KT Cloud Driver: called createClient()") + // cblogger.Infof("### connectionInfo.RegionInfo.Zone : [%d]", connectionInfo.RegionInfo.Zone) + + // $$$ Caution!! + var apiurl string + if strings.EqualFold(connectionInfo.RegionInfo.Zone, KOR_Seoul_M2_ZoneID) { // When Zone is "KOR-Seoul M2" + apiurl = "https://api.ucloudbiz.olleh.com/server/v2/client/api" + } else { + apiurl = "https://api.ucloudbiz.olleh.com/server/v1/client/api" + } + + if len(apiurl) == 0 { + newErr := fmt.Errorf("KT Cloud API URL Not Found!!") + cblogger.Error(newErr.Error()) + return nil, newErr + } + + apikey := connectionInfo.CredentialInfo.ClientId + if len(apikey) == 0 { + newErr := fmt.Errorf("KT Cloud API Key Not Found!!") + cblogger.Error(newErr.Error()) + return nil, newErr + } + + secretkey := connectionInfo.CredentialInfo.ClientSecret + if len(secretkey) == 0 { + newErr := fmt.Errorf("KT Cloud Secret Key Not Found!!") + cblogger.Error(newErr.Error()) + return nil, newErr + } + + // Always validate any SSL certificates in the chain + insecureskipverify := false + client := ktsdk.KtCloudClient{}.New(apiurl, apikey, secretkey, insecureskipverify) + + return client, nil +} + +func getSeoulCurrentTime() string { + loc, _ := time.LoadLocation("Asia/Seoul") + currentTime := time.Now().In(loc) + return currentTime.Format("2006-01-02 15:04:05") +} diff --git a/cloud-control-manager/cloud-driver/drivers/ktcloud/resources/SecurityHandler.go b/cloud-control-manager/cloud-driver/drivers/ktcloud/resources/SecurityHandler.go index 1976b0a1f..131a1d6ff 100644 --- a/cloud-control-manager/cloud-driver/drivers/ktcloud/resources/SecurityHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ktcloud/resources/SecurityHandler.go @@ -7,6 +7,7 @@ // KT Cloud Security Group Handler // // by ETRI, 2021.05. +// Updated by ETRI, 2024.09. package resources @@ -18,14 +19,13 @@ import ( // "crypto/aes" // "crypto/cipher" "encoding/base64" - // "github.com/davecgh/go-spew/spew" - ktsdk "github.com/cloud-barista/ktcloud-sdk-go" - "encoding/json" "errors" // "strconv" + ktsdk "github.com/cloud-barista/ktcloud-sdk-go" + cblog "github.com/cloud-barista/cb-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" @@ -48,10 +48,11 @@ func init() { } type SecurityGroup struct { - IID IId `json:"IId"` - VpcIID VpcIId `json:"VpcIID"` - Direc string `json:"Direction"` - Secu_Rules []Security_Rule `json:"SecurityRules"` + IID IId `json:"IId"` + VpcIID VpcIId `json:"VpcIID"` + Direc string `json:"Direction"` + Secu_Rules []Security_Rule `json:"SecurityRules"` + KeyValue_List []KeyValue `json:"KeyValueList"` } type IId struct { @@ -74,6 +75,7 @@ type Security_Rule struct { func (securityHandler *KtCloudSecurityHandler) CreateSecurity(securityReqInfo irs.SecurityReqInfo) (irs.SecurityInfo, error) { cblogger.Info("KT Cloud cloud driver: called CreateSecurity()!") + zoneId := securityHandler.RegionInfo.Zone if zoneId == "" { cblogger.Error("Failed to Get Zone info. from the connection info.") @@ -106,15 +108,33 @@ func (securityHandler *KtCloudSecurityHandler) CreateSecurity(securityReqInfo ir for _, sg := range sgList { if sg.IId.NameId == securityReqInfo.IId.NameId { createErr := errors.New("Security Group with name " + securityReqInfo.IId.NameId + " already exists", ) + cblogger.Error(createErr.Error()) return irs.SecurityInfo{}, createErr } } + currentTime := getSeoulCurrentTime() + + newSGInfo := irs.SecurityInfo{ + IId: irs.IID{ + NameId: securityReqInfo.IId.NameId, + // Caution!! : securityReqInfo.IId.NameId -> SystemId + SystemId: securityReqInfo.IId.NameId, + }, + VpcIID: securityReqInfo.VpcIID, + SecurityRules: securityReqInfo.SecurityRules, + KeyValueList: []irs.KeyValue{ + {Key: "KTCloud-SecuriyGroup-info.", Value: "This SecuriyGroup info. is temporary."}, + {Key: "CreateTime", Value: currentTime}, + }, + } + // spew.Dump(newSGInfo) + hashFileName := base64.StdEncoding.EncodeToString([]byte(securityReqInfo.IId.NameId)) cblogger.Infof("# S/G NameId : "+ securityReqInfo.IId.NameId) - cblogger.Infof("# Hashed FileName : "+ hashFileName + ".json") + // cblogger.Infof("# Hashed FileName : "+ hashFileName + ".json") - file, _ := json.MarshalIndent(securityReqInfo, "", " ") + file, _ := json.MarshalIndent(newSGInfo, "", " ") writeErr := os.WriteFile(sgFilePath + hashFileName + ".json", file, 0644) if writeErr != nil { cblogger.Error("Failed to write the file: "+ sgFilePath + hashFileName + ".json", writeErr) @@ -139,7 +159,7 @@ func (securityHandler *KtCloudSecurityHandler) GetSecurity(securityIID irs.IID) hashFileName := base64.StdEncoding.EncodeToString([]byte(securityIID.NameId)) cblogger.Infof("# securityIID.NameId : "+ securityIID.NameId) - cblogger.Infof("# hashFileName : "+ hashFileName + ".json") + // cblogger.Infof("# hashFileName : "+ hashFileName + ".json") zoneId := securityHandler.RegionInfo.Zone if zoneId == "" { @@ -177,15 +197,15 @@ func (securityHandler *KtCloudSecurityHandler) GetSecurity(securityIID irs.IID) byteValue, readErr := io.ReadAll(jsonFile) if readErr != nil { cblogger.Error("Failed to Read the S/G file : "+ sgFileName, readErr) + return irs.SecurityInfo{}, readErr } json.Unmarshal(byteValue, &sg) // spew.Dump(sg) - // Caution : ~~~ := mappingSecurityInfo( ) => ~~~ := securityHandler.mappingSecurityInfo( ) - securityGroupInfo, securityInfoError := securityHandler.mappingSecurityInfo(sg) - if securityInfoError != nil { - cblogger.Error(securityInfoError) - return irs.SecurityInfo{}, securityInfoError + securityGroupInfo, mapError := securityHandler.mappingSecurityInfo(sg) + if mapError != nil { + cblogger.Error(mapError) + return irs.SecurityInfo{}, mapError } return securityGroupInfo, nil } @@ -298,34 +318,36 @@ func (securityHandler *KtCloudSecurityHandler) DeleteSecurity(securityIID irs.II return true, nil } -func (securityHandler *KtCloudSecurityHandler) mappingSecurityInfo(secuGroup SecurityGroup) (irs.SecurityInfo, error) { +func (securityHandler *KtCloudSecurityHandler) mappingSecurityInfo(sg SecurityGroup) (irs.SecurityInfo, error) { cblogger.Info("KT Cloud cloud driver: called mappingSecurityInfo()!") - var securityRuleList []irs.SecurityRuleInfo - var securityRuleInfo irs.SecurityRuleInfo - - for i := 0; i < len(secuGroup.Secu_Rules); i++ { - securityRuleInfo.FromPort = secuGroup.Secu_Rules[i].FromPort - securityRuleInfo.ToPort = secuGroup.Secu_Rules[i].ToPort - securityRuleInfo.IPProtocol = secuGroup.Secu_Rules[i].Protocol //KT Cloud S/G의 경우, TCP, UDP, ICMP 가능 - securityRuleInfo.Direction = secuGroup.Secu_Rules[i].Direc //KT Cloud S/G의 경우 inbound rule만 지원 - securityRuleInfo.CIDR = secuGroup.Secu_Rules[i].Cidr + var sgRuleList []irs.SecurityRuleInfo + var sgRuleInfo irs.SecurityRuleInfo + var sgKeyValue irs.KeyValue + var sgKeyValueList []irs.KeyValue + + for i := 0; i < len(sg.Secu_Rules); i++ { + sgRuleInfo.FromPort = sg.Secu_Rules[i].FromPort + sgRuleInfo.ToPort = sg.Secu_Rules[i].ToPort + sgRuleInfo.IPProtocol = sg.Secu_Rules[i].Protocol // For KT Cloud Classic S/G, TCP/UDP/ICMP is available + sgRuleInfo.Direction = sg.Secu_Rules[i].Direc // For KT Cloud Classic S/G, supports only inbound rule. + sgRuleInfo.CIDR = sg.Secu_Rules[i].Cidr - securityRuleList = append(securityRuleList, securityRuleInfo) + sgRuleList = append(sgRuleList, sgRuleInfo) } + for k := 0; k < len(sg.KeyValue_List); k++ { + sgKeyValue.Key = sg.KeyValue_List[k].Key + sgKeyValue.Value = sg.KeyValue_List[k].Value + sgKeyValueList = append(sgKeyValueList, sgKeyValue) + } + securityInfo := irs.SecurityInfo{ - IId: irs.IID{NameId: secuGroup.IID.NameID, SystemId: secuGroup.IID.NameID}, + IId: irs.IID{NameId: sg.IID.NameID, SystemId: sg.IID.NameID}, //KT Cloud의 CB에서 파일로 관리되므로 SystemId는 NameId와 동일하게 - VpcIID: irs.IID{NameId: secuGroup.VpcIID.NameID, SystemId: secuGroup.VpcIID.SystemID}, - SecurityRules: &securityRuleList, - - // KeyValueList: []irs.KeyValue{ - // {Key: "IpAddress", Value: KtCloudFirewallRule.IpAddress}, - // {Key: "IpAddressID", Value: KtCloudFirewallRule.IpAddressId}, - // {Key: "State", Value: KtCloudFirewallRule.State}, - // }, + VpcIID: irs.IID{NameId: sg.VpcIID.NameID, SystemId: sg.VpcIID.SystemID}, + SecurityRules: &sgRuleList, + KeyValueList: sgKeyValueList, } - return securityInfo, nil } diff --git a/cloud-control-manager/cloud-driver/drivers/ktcloud/resources/VPCHandler.go b/cloud-control-manager/cloud-driver/drivers/ktcloud/resources/VPCHandler.go index 89b7dcabc..69bc623ca 100644 --- a/cloud-control-manager/cloud-driver/drivers/ktcloud/resources/VPCHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ktcloud/resources/VPCHandler.go @@ -62,17 +62,17 @@ type KeyValue struct { Value string `json:"Value"` } -func (VPCHandler *KtCloudVPCHandler) CreateVPC(vpcReqInfo irs.VPCReqInfo) (irs.VPCInfo, error) { +func (vpcHandler *KtCloudVPCHandler) CreateVPC(vpcReqInfo irs.VPCReqInfo) (irs.VPCInfo, error) { cblogger.Info("KT Cloud Cloud Driver: called CreateVPC()!") // Check if the VPC Name already Exists - vpcInfo, _ := VPCHandler.GetVPC(irs.IID{SystemId: vpcReqInfo.IId.NameId}) + vpcInfo, _ := vpcHandler.GetVPC(irs.IID{SystemId: vpcReqInfo.IId.NameId}) if vpcInfo.IId.SystemId != "" { cblogger.Error("The VPC already exists .") return irs.VPCInfo{}, errors.New("The VPC already exists.") } - zoneId := VPCHandler.RegionInfo.Zone + zoneId := vpcHandler.RegionInfo.Zone if zoneId == "" { cblogger.Error("Failed to Get Zone info. from the connection info.") return irs.VPCInfo{}, errors.New("Failed to Get Zone info. from the connection info.") @@ -84,13 +84,15 @@ func (VPCHandler *KtCloudVPCHandler) CreateVPC(vpcReqInfo irs.VPCReqInfo) (irs.V for _, curSubnet := range vpcReqInfo.SubnetInfoList { cblogger.Infof("Subnet NameId : %s", curSubnet.IId.NameId) - newSubnet, subnetErr := VPCHandler.CreateSubnet(curSubnet) + newSubnet, subnetErr := vpcHandler.CreateSubnet(curSubnet) if subnetErr != nil { return irs.VPCInfo{}, subnetErr } subnetList = append(subnetList, newSubnet) } + currentTime := getSeoulCurrentTime() + newVpcInfo := irs.VPCInfo{ IId: irs.IID{ NameId: vpcReqInfo.IId.NameId, @@ -101,6 +103,7 @@ func (VPCHandler *KtCloudVPCHandler) CreateVPC(vpcReqInfo irs.VPCReqInfo) (irs.V SubnetInfoList: subnetList, KeyValueList: []irs.KeyValue{ {Key: "KTCloud-VPC-info.", Value: "This VPC info. is temporary."}, + {Key: "CreateTime", Value: currentTime}, }, } // spew.Dump(newVpcInfo) @@ -131,12 +134,12 @@ func (VPCHandler *KtCloudVPCHandler) CreateVPC(vpcReqInfo irs.VPCReqInfo) (irs.V cblogger.Error("Failed to write the file: "+jsonFileName, writeErr) return irs.VPCInfo{}, writeErr } - cblogger.Infof("Succeeded in writing the VPC info file: " + jsonFileName) - cblogger.Info("Succeeded in Creating the VPC : " + newVpcInfo.IId.NameId) + // cblogger.Infof("Succeeded in writing the VPC info file: " + jsonFileName) + // cblogger.Info("Succeeded in Creating the VPC : " + newVpcInfo.IId.NameId) // Because it's managed as a file, there's no SystemId created. // Return the created SecurityGroup info. - vpcInfo, vpcErr := VPCHandler.GetVPC(irs.IID{SystemId: vpcReqInfo.IId.NameId}) + vpcInfo, vpcErr := vpcHandler.GetVPC(irs.IID{SystemId: vpcReqInfo.IId.NameId}) if vpcErr != nil { cblogger.Error("Failed to Get the VPC info.") return irs.VPCInfo{}, vpcErr @@ -144,7 +147,7 @@ func (VPCHandler *KtCloudVPCHandler) CreateVPC(vpcReqInfo irs.VPCReqInfo) (irs.V return vpcInfo, nil } -func (VPCHandler *KtCloudVPCHandler) GetVPC(vpcIID irs.IID) (irs.VPCInfo, error) { +func (vpcHandler *KtCloudVPCHandler) GetVPC(vpcIID irs.IID) (irs.VPCInfo, error) { cblogger.Info("KT Cloud Cloud Driver: called GetVPC()!") //Caution!! @@ -152,7 +155,7 @@ func (VPCHandler *KtCloudVPCHandler) GetVPC(vpcIID irs.IID) (irs.VPCInfo, error) vpcIID.NameId = vpcIID.SystemId } - zoneId := VPCHandler.RegionInfo.Zone + zoneId := vpcHandler.RegionInfo.Zone if zoneId == "" { cblogger.Error("Failed to Get Zone info. from the connection info.") @@ -199,7 +202,7 @@ func (VPCHandler *KtCloudVPCHandler) GetVPC(vpcIID irs.IID) (irs.VPCInfo, error) var vpcFileInfo VPCFileInfo json.Unmarshal(byteValue, &vpcFileInfo) - vpcInfo, vpcInfoError := VPCHandler.mappingVPCInfo(vpcFileInfo) + vpcInfo, vpcInfoError := vpcHandler.mappingVPCInfo(vpcFileInfo) if vpcInfoError != nil { cblogger.Error(vpcInfoError) return irs.VPCInfo{}, vpcInfoError @@ -207,10 +210,10 @@ func (VPCHandler *KtCloudVPCHandler) GetVPC(vpcIID irs.IID) (irs.VPCInfo, error) return vpcInfo, nil } -func (VPCHandler *KtCloudVPCHandler) ListVPC() ([]*irs.VPCInfo, error) { +func (vpcHandler *KtCloudVPCHandler) ListVPC() ([]*irs.VPCInfo, error) { cblogger.Info("KT Cloud Cloud Driver: called ListVPC()!") - zoneId := VPCHandler.RegionInfo.Zone + zoneId := vpcHandler.RegionInfo.Zone if zoneId == "" { cblogger.Error("Failed to Get Zone info. from the connection info.") @@ -234,7 +237,7 @@ func (VPCHandler *KtCloudVPCHandler) ListVPC() ([]*irs.VPCInfo, error) { vpcIID.NameId = fileName cblogger.Infof("# VPC Name : " + vpcIID.NameId) - vpcInfo, getVpcErr := VPCHandler.GetVPC(irs.IID{SystemId: vpcIID.NameId}) + vpcInfo, getVpcErr := vpcHandler.GetVPC(irs.IID{SystemId: vpcIID.NameId}) if getVpcErr != nil { cblogger.Errorf("Failed to Find the VPC : %s", vpcIID.SystemId) return []*irs.VPCInfo{}, getVpcErr @@ -244,7 +247,7 @@ func (VPCHandler *KtCloudVPCHandler) ListVPC() ([]*irs.VPCInfo, error) { return vpcInfoList, nil } -func (VPCHandler *KtCloudVPCHandler) DeleteVPC(vpcIID irs.IID) (bool, error) { +func (vpcHandler *KtCloudVPCHandler) DeleteVPC(vpcIID irs.IID) (bool, error) { cblogger.Info("KT Cloud Cloud Driver: called DeleteVPC()!") if vpcIID.SystemId != "" { @@ -252,13 +255,13 @@ func (VPCHandler *KtCloudVPCHandler) DeleteVPC(vpcIID irs.IID) (bool, error) { } //To check whether the VPC exists. - _, getVpcErr := VPCHandler.GetVPC(irs.IID{SystemId: vpcIID.NameId}) + _, getVpcErr := vpcHandler.GetVPC(irs.IID{SystemId: vpcIID.NameId}) if getVpcErr != nil { cblogger.Errorf("Failed to Find the VPC : %s", vpcIID.NameId) return false, getVpcErr } - zoneId := VPCHandler.RegionInfo.Zone + zoneId := vpcHandler.RegionInfo.Zone if zoneId == "" { cblogger.Error("Failed to Get Zone info. from the connection info.") return false, errors.New("Failed to Get Zone info. from the connection info.") @@ -298,46 +301,49 @@ func (VPCHandler *KtCloudVPCHandler) DeleteVPC(vpcIID irs.IID) (bool, error) { return true, nil } -func (VPCHandler *KtCloudVPCHandler) AddSubnet(vpcIID irs.IID, subnetInfo irs.SubnetInfo) (irs.VPCInfo, error) { +func (vpcHandler *KtCloudVPCHandler) AddSubnet(vpcIID irs.IID, subnetInfo irs.SubnetInfo) (irs.VPCInfo, error) { cblogger.Info("KT Cloud cloud driver: called AddSubnet()!!") return irs.VPCInfo{}, errors.New("Does not support AddSubnet() yet!!") } -func (VPCHandler *KtCloudVPCHandler) RemoveSubnet(vpcIID irs.IID, subnetIID irs.IID) (bool, error) { +func (vpcHandler *KtCloudVPCHandler) RemoveSubnet(vpcIID irs.IID, subnetIID irs.IID) (bool, error) { cblogger.Info("KT Cloud cloud driver: called GetImage()!!") return true, errors.New("Does not support RemoveSubnet() yet!!") } -func (VPCHandler *KtCloudVPCHandler) CreateSubnet(subnetReqInfo irs.SubnetInfo) (irs.SubnetInfo, error) { +func (vpcHandler *KtCloudVPCHandler) CreateSubnet(subnetReqInfo irs.SubnetInfo) (irs.SubnetInfo, error) { cblogger.Info("KT Cloud cloud driver: called CreateSubnet()!!") - // zoneId := VPCHandler.RegionInfo.Zone + // zoneId := vpcHandler.RegionInfo.Zone // cblogger.Infof("ZoneId : %s", zoneId) // if zoneId == "" { // cblogger.Error("Failed to Get Zone info. from the connection info.") // return irs.SubnetInfo{}, errors.New("Failed to Get Zone info. from the connection info.") // } + currentTime := getSeoulCurrentTime() + newSubnetInfo := irs.SubnetInfo{ IId: irs.IID{ NameId: subnetReqInfo.IId.NameId, // Caution!! : subnetReqInfo.IId.NameId -> SystemId SystemId: subnetReqInfo.IId.NameId, }, - Zone: subnetReqInfo.Zone, + Zone: subnetReqInfo.Zone, IPv4_CIDR: "N/A", KeyValueList: []irs.KeyValue{ {Key: "KTCloud-Subnet-info.", Value: "This Subne info. is temporary."}, + {Key: "CreateTime", Value: currentTime}, }, } return newSubnetInfo, nil } -func (VPCHandler *KtCloudVPCHandler) mappingVPCInfo(vpcFileInfo VPCFileInfo) (irs.VPCInfo, error) { +func (vpcHandler *KtCloudVPCHandler) mappingVPCInfo(vpcFileInfo VPCFileInfo) (irs.VPCInfo, error) { cblogger.Info("KT Cloud cloud driver: called mappingVPCInfo()!!") - var subnetInfoList []irs.SubnetInfo var subnetInfo irs.SubnetInfo + var subnetInfoList []irs.SubnetInfo var subnetKeyValue irs.KeyValue var subnetKeyValueList []irs.KeyValue var vpcKeyValue irs.KeyValue @@ -375,6 +381,48 @@ func (VPCHandler *KtCloudVPCHandler) mappingVPCInfo(vpcFileInfo VPCFileInfo) (ir return vpcInfo, nil } +func (vpcHandler *KtCloudVPCHandler) getSubnetZone(vpcIID irs.IID, subnetIID irs.IID) (string, error) { + cblogger.Info("KT Cloud cloud driver: called getSubnetZone()!!") + + if strings.EqualFold(vpcIID.SystemId, "") && strings.EqualFold(vpcIID.NameId, ""){ + newErr := fmt.Errorf("Invalid VPC Id!!") + cblogger.Error(newErr.Error()) + return "", newErr + } + + if strings.EqualFold(subnetIID.SystemId, "") && strings.EqualFold(subnetIID.NameId, ""){ + newErr := fmt.Errorf("Invalid Subnet Id!!") + cblogger.Error(newErr.Error()) + return "", newErr + } + + // Get the VPC information + vpcInfo, err := vpcHandler.GetVPC(vpcIID) + if err != nil { + newErr := fmt.Errorf("Failed to Get the VPC Info : [%v]", err) + cblogger.Error(newErr.Error()) + return "", newErr + } + // cblogger.Info("\n\n### vpcInfo : ") + // spew.Dump(vpcInfo) + // cblogger.Info("\n") + + // Get the Zone info of the specified Subnet + var subnetZone string + for _, subnet := range vpcInfo.SubnetInfoList { + if strings.EqualFold(subnet.IId.SystemId, subnetIID.SystemId) { + subnetZone = subnet.Zone + break + } + } + if strings.EqualFold(subnetZone, "") { + newErr := fmt.Errorf("Failed to Get the Zone info of the specified Subnet!!") + cblogger.Error(newErr.Error()) + return "", newErr + } + return subnetZone, nil +} + func (vpcHandler *KtCloudVPCHandler) ListIID() ([]*irs.IID, error) { cblogger.Info("Cloud driver: called ListIID()!!") return nil, errors.New("Does not support ListIID() yet!!") diff --git a/cloud-control-manager/cloud-driver/drivers/ktcloudvpc/resources/CommonKTCloudFunc.go b/cloud-control-manager/cloud-driver/drivers/ktcloudvpc/resources/CommonKTCloudFunc.go index ab61cabfc..1673f75d8 100644 --- a/cloud-control-manager/cloud-driver/drivers/ktcloudvpc/resources/CommonKTCloudFunc.go +++ b/cloud-control-manager/cloud-driver/drivers/ktcloudvpc/resources/CommonKTCloudFunc.go @@ -225,3 +225,9 @@ func ipToCidr24(ipStr string) (string, error) { network := ip.Mask(mask) return fmt.Sprintf("%s/24", network), nil } + +func getSeoulCurrentTime() string { + loc, _ := time.LoadLocation("Asia/Seoul") + currentTime := time.Now().In(loc) + return currentTime.Format("2006-01-02 15:04:05") +} diff --git a/cloud-control-manager/cloud-driver/drivers/ktcloudvpc/resources/SecurityHandler.go b/cloud-control-manager/cloud-driver/drivers/ktcloudvpc/resources/SecurityHandler.go index 1732d4b1f..0acf6f21f 100644 --- a/cloud-control-manager/cloud-driver/drivers/ktcloudvpc/resources/SecurityHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/ktcloudvpc/resources/SecurityHandler.go @@ -7,6 +7,7 @@ // KT Cloud Security Group Handler // // by ETRI, 2022.12. +// Updated by ETRI, 2024.09. package resources @@ -16,7 +17,6 @@ import ( "io" "os" "strings" - // "crypto/aes" // "crypto/cipher" "encoding/base64" @@ -48,10 +48,16 @@ func init() { } type SecurityGroup struct { - IID IId `json:"IId"` - VpcIID VpcIId `json:"VpcIID"` - Direc string `json:"Direction"` - Secu_Rules []Security_Rule `json:"SecurityRules"` + IID IId `json:"IId"` + VpcIID VpcIId `json:"VpcIID"` + Direc string `json:"Direction"` + Secu_Rules []Security_Rule `json:"SecurityRules"` + KeyValue_List []KeyValue `json:"KeyValueList"` +} + +type KeyValue struct { + Key string `json:"Key"` + Value string `json:"Value"` } type IId struct { @@ -115,12 +121,28 @@ func (securityHandler *KTVpcSecurityHandler) CreateSecurity(securityReqInfo irs. } } + currentTime := getSeoulCurrentTime() + + newSGInfo := irs.SecurityInfo{ + IId: irs.IID{ + NameId: securityReqInfo.IId.NameId, + // Caution!! : securityReqInfo.IId.NameId -> SystemId + SystemId: securityReqInfo.IId.NameId, + }, + VpcIID: securityReqInfo.VpcIID, + SecurityRules: securityReqInfo.SecurityRules, + KeyValueList: []irs.KeyValue{ + {Key: "KTCloud-SecuriyGroup-info.", Value: "This SecuriyGroup info. is temporary."}, + {Key: "CreateTime", Value: currentTime}, + }, + } + // spew.Dump(newSGInfo) + hashFileName := base64.StdEncoding.EncodeToString([]byte(securityReqInfo.IId.NameId)) cblogger.Infof("# S/G NameId : " + securityReqInfo.IId.NameId) - cblogger.Infof("# Hashed FileName : " + hashFileName + ".json") - - file, _ := json.MarshalIndent(securityReqInfo, "", " ") + // cblogger.Infof("# Hashed FileName : " + hashFileName + ".json") + file, _ := json.MarshalIndent(newSGInfo, "", " ") writeErr := os.WriteFile(sgFilePath+hashFileName+".json", file, 0644) if writeErr != nil { cblogger.Error("Failed to write the file: "+sgFilePath+hashFileName+".json", writeErr) @@ -150,7 +172,7 @@ func (securityHandler *KTVpcSecurityHandler) GetSecurity(securityIID irs.IID) (i hashFileName := base64.StdEncoding.EncodeToString([]byte(securityIID.NameId)) cblogger.Infof("# securityIID.NameId : " + securityIID.NameId) - cblogger.Infof("# hashFileName : " + hashFileName + ".json") + // cblogger.Infof("# hashFileName : " + hashFileName + ".json") if strings.EqualFold(securityHandler.RegionInfo.Zone, "") { newErr := fmt.Errorf("Invalid Region Info!!") @@ -186,16 +208,15 @@ func (securityHandler *KTVpcSecurityHandler) GetSecurity(securityIID irs.IID) (i byteValue, readErr := io.ReadAll(jsonFile) if readErr != nil { cblogger.Error("Failed to Read the S/G file : "+sgFileName, readErr) + return irs.SecurityInfo{}, readErr } json.Unmarshal(byteValue, &sg) - // spew.Dump(sg) - // Caution : ~~~ := mappingSecurityInfo( ) => ~~~ := securityHandler.mappingSecurityInfo( ) - securityGroupInfo, securityInfoError := securityHandler.mappingSecurityInfo(sg) - if securityInfoError != nil { - cblogger.Error(securityInfoError) - return irs.SecurityInfo{}, securityInfoError + securityGroupInfo, mapError := securityHandler.mappingSecurityInfo(sg) + if mapError != nil { + cblogger.Error(mapError) + return irs.SecurityInfo{}, mapError } return securityGroupInfo, nil } @@ -322,33 +343,36 @@ func (securityHandler *KTVpcSecurityHandler) RemoveRules(sgIID irs.IID, security return false, fmt.Errorf("Does not support RemoveRules() yet!!") } -func (securityHandler *KTVpcSecurityHandler) mappingSecurityInfo(secuGroup SecurityGroup) (irs.SecurityInfo, error) { +func (securityHandler *KTVpcSecurityHandler) mappingSecurityInfo(sg SecurityGroup) (irs.SecurityInfo, error) { cblogger.Info("KT Cloud VPC driver: called mappingSecurityInfo()!") - var securityRuleList []irs.SecurityRuleInfo - var securityRuleInfo irs.SecurityRuleInfo - - for i := 0; i < len(secuGroup.Secu_Rules); i++ { - securityRuleInfo.FromPort = secuGroup.Secu_Rules[i].FromPort - securityRuleInfo.ToPort = secuGroup.Secu_Rules[i].ToPort - securityRuleInfo.IPProtocol = secuGroup.Secu_Rules[i].Protocol // For KT Cloud VPC S/G, TCP/UDP/ICMP is available - securityRuleInfo.Direction = secuGroup.Secu_Rules[i].Direc // For KT Cloud VPC S/G, supports inbound/outbound rule. - securityRuleInfo.CIDR = secuGroup.Secu_Rules[i].Cidr - - securityRuleList = append(securityRuleList, securityRuleInfo) + var sgRuleList []irs.SecurityRuleInfo + var sgRuleInfo irs.SecurityRuleInfo + var sgKeyValue irs.KeyValue + var sgKeyValueList []irs.KeyValue + + for i := 0; i < len(sg.Secu_Rules); i++ { + sgRuleInfo.FromPort = sg.Secu_Rules[i].FromPort + sgRuleInfo.ToPort = sg.Secu_Rules[i].ToPort + sgRuleInfo.IPProtocol = sg.Secu_Rules[i].Protocol // For KT Cloud VPC S/G, TCP/UDP/ICMP is available + sgRuleInfo.Direction = sg.Secu_Rules[i].Direc // For KT Cloud VPC S/G, supports inbound/outbound rule. + sgRuleInfo.CIDR = sg.Secu_Rules[i].Cidr + + sgRuleList = append(sgRuleList, sgRuleInfo) + } + + for k := 0; k < len(sg.KeyValue_List); k++ { + sgKeyValue.Key = sg.KeyValue_List[k].Key + sgKeyValue.Value = sg.KeyValue_List[k].Value + sgKeyValueList = append(sgKeyValueList, sgKeyValue) } securityInfo := irs.SecurityInfo{ - IId: irs.IID{NameId: secuGroup.IID.NameID, SystemId: secuGroup.IID.NameID}, + IId: irs.IID{NameId: sg.IID.NameID, SystemId: sg.IID.NameID}, // Since it is managed as a file, the systemID is the same as the name ID. - VpcIID: irs.IID{NameId: secuGroup.VpcIID.NameID, SystemId: secuGroup.VpcIID.SystemID}, - SecurityRules: &securityRuleList, - - // KeyValueList: []irs.KeyValue{ - // {Key: "IpAddress", Value: KtCloudFirewallRule.IpAddress}, - // {Key: "IpAddressID", Value: KtCloudFirewallRule.IpAddressId}, - // {Key: "State", Value: KtCloudFirewallRule.State}, - // }, + VpcIID: irs.IID{NameId: sg.VpcIID.NameID, SystemId: sg.VpcIID.SystemID}, + SecurityRules: &sgRuleList, + KeyValueList: sgKeyValueList, } return securityInfo, nil }