Skip to content

Commit

Permalink
Merge pull request #159 from MZC-CSC/issue_1067_add_default_regionzone
Browse files Browse the repository at this point in the history
  • Loading branch information
MZC-CSC authored Apr 12, 2024
2 parents fafe0d6 + fbce7f2 commit 4834183
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,12 @@ func WaitOperationComplete(client *compute.Service, project string, region strin
func GetDiskInfo(client *compute.Service, credential idrv.CredentialInfo, region idrv.RegionInfo, diskName string) (*compute.Disk, error) {
projectID := credential.ProjectID
zone := region.Zone
targetZone := region.TargetZone

// 대상 zone이 다른경우 targetZone을 사용
if targetZone != ""{
zone = targetZone
}
diskResp, err := client.Disks.Get(projectID, zone, diskName).Do()
if err != nil {
cblogger.Error(err)
Expand Down
117 changes: 100 additions & 17 deletions cloud-control-manager/cloud-driver/drivers/gcp/resources/DiskHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ func (DiskHandler *GCPDiskHandler) CreateDisk(diskReqInfo irs.DiskInfo) (irs.Dis
zone := DiskHandler.Region.Zone
diskName := diskReqInfo.IId.NameId

if diskReqInfo.Zone != "" {// #1067 disk의 zone이 있으면 해당 zone 사용.
cblogger.Info("SetDisk zone before ", DiskHandler.Region)
zone = diskReqInfo.Zone
DiskHandler.Region.Zone = zone // Region은 동일할 것이고 zone을 새로 설정.
cblogger.Info("SetDisk zone after ", DiskHandler.Region)
}

disk := &compute.Disk{
Name: diskName,
}
Expand Down Expand Up @@ -79,7 +86,7 @@ func (DiskHandler *GCPDiskHandler) CreateDisk(diskReqInfo irs.DiskInfo) (irs.Dis

// Disk 생성 대기
WaitOperationComplete(DiskHandler.Client, projectID, region, zone, op.Name, 3)

cblogger.Info("GetDisk zone ", DiskHandler.Region)
diskInfo, errDiskInfo := DiskHandler.GetDisk(irs.IID{NameId: diskName, SystemId: diskName})
if errDiskInfo != nil {
cblogger.Error(errDiskInfo)
Expand All @@ -96,33 +103,59 @@ func (DiskHandler *GCPDiskHandler) ListDisk() ([]*irs.DiskInfo, error) {
diskInfoList := []*irs.DiskInfo{}

projectID := DiskHandler.Credential.ProjectID
zone := DiskHandler.Region.Zone

diskList, err := DiskHandler.Client.Disks.List(projectID, zone).Do()
hiscallInfo.ElapsedTime = call.Elapsed(start)
regionID := DiskHandler.Region.Region
//zone := DiskHandler.Region.Zone

cblogger.Error("get ZoneInfo by region ")
//GetRegionZone(regionName string) (irs.RegionZoneInfo, error)
// #1067에 의해 connection의 zone -> region내 disk 조회로 변경
regionZoneHandler := GCPRegionZoneHandler{
Client: DiskHandler.Client,
Credential : DiskHandler.Credential,
Region:DiskHandler.Region,
Ctx : DiskHandler.Ctx,
}
regionZoneInfo, err := regionZoneHandler.GetRegionZone(regionID)
if err != nil {
cblogger.Error("failed to get ZoneInfo by region ", err)
// failed to get ZoneInfo by region
cblogger.Error(err)
LoggingError(hiscallInfo, err)
return nil, err
}
calllogger.Info(call.String(hiscallInfo))

for _, disk := range diskList.Items {
diskInfo, err := convertDiskInfo(disk)
if err != nil {
cblogger.Error(err)
return nil, err
} else {
cblogger.Error("get region zone Info ", regionZoneInfo)
for _, zoneItem := range regionZoneInfo.ZoneList {
cblogger.Error("zone Info ", zoneItem)
// get Disks by Zone
hiscallInfo.ElapsedTime = call.Elapsed(start)
diskList, err := DiskHandler.Client.Disks.List(projectID, zoneItem.Name).Do()
if err != nil {
cblogger.Error(err)
LoggingError(hiscallInfo, err)
return nil, err
}
calllogger.Info(call.String(hiscallInfo))

for _, disk := range diskList.Items {
diskInfo, err := convertDiskInfo(disk)
if err != nil {
cblogger.Error(err)
return nil, err
}
diskInfoList = append(diskInfoList, &diskInfo)
}
}
diskInfoList = append(diskInfoList, &diskInfo)

}



return diskInfoList, nil
}

func (DiskHandler *GCPDiskHandler) GetDisk(diskIID irs.IID) (irs.DiskInfo, error) {
hiscallInfo := GetCallLogScheme(DiskHandler.Region, call.DISK, diskIID.NameId, "GetDisk()")
start := call.Start()

cblogger.Info("GetDisk zone ", DiskHandler.Region)
diskResp, err := GetDiskInfo(DiskHandler.Client, DiskHandler.Credential, DiskHandler.Region, diskIID.SystemId)
hiscallInfo.ElapsedTime = call.Elapsed(start)
if err != nil {
Expand Down Expand Up @@ -192,8 +225,14 @@ func (DiskHandler *GCPDiskHandler) DeleteDisk(diskIID irs.IID) (bool, error) {
projectID := DiskHandler.Credential.ProjectID
region := DiskHandler.Region.Region
zone := DiskHandler.Region.Zone
targetZone := DiskHandler.Region.TargetZone
disk := diskIID.SystemId

// 대상 zone이 다른경우 targetZone을 사용
if targetZone != ""{
zone = targetZone
}

op, err := DiskHandler.Client.Disks.Delete(projectID, zone, disk).Do()
hiscallInfo.ElapsedTime = call.Elapsed(start)
if err != nil {
Expand All @@ -210,12 +249,47 @@ func (DiskHandler *GCPDiskHandler) DeleteDisk(diskIID irs.IID) (bool, error) {
}

func (DiskHandler *GCPDiskHandler) AttachDisk(diskIID irs.IID, ownerVM irs.IID) (irs.DiskInfo, error) {
// disk와 vm의 zone valid check
attachDiskInfo, err := DiskHandler.GetDisk(diskIID)
if err != nil {
cblogger.Error(err)
return irs.DiskInfo{}, err
}

// check disk status : "available" state only
if attachDiskInfo.Status != irs.DiskStatus("Available") {
return irs.DiskInfo{}, errors.New(string("The disk must be in the Available state : " + attachDiskInfo.Status))
}

vmHandler := GCPVMHandler{
Client: DiskHandler.Client,
Region: DiskHandler.Region,
Ctx: DiskHandler.Ctx,
Credential: DiskHandler.Credential,
}
vmInfo, err := vmHandler.GetVmById(ownerVM)
if err != nil {
cblogger.Error(err.Error())
return irs.DiskInfo{}, err
}


if vmInfo.Region.Zone != attachDiskInfo.Zone{
cblogger.Error("The disk and the VM must be in the same zone." + vmInfo.Region.Zone, attachDiskInfo.Zone)
return irs.DiskInfo{}, errors.New(string("The disk and the VM must be in the same zone."))
}

// vmStatus는 다시 조회해야 하기 때문에 attach할 수 있는 상태가 아니면 오류로 return
// valid check end


hiscallInfo := GetCallLogScheme(DiskHandler.Region, call.DISK, diskIID.NameId, "AttachDisk()")
start := call.Start()

projectID := DiskHandler.Credential.ProjectID
region := DiskHandler.Region.Region
zone := DiskHandler.Region.Zone
//zone := DiskHandler.Region.Zone
zone := vmInfo.Region.Zone// vm의 zone으로 설정
instance := ownerVM.SystemId

attachedDisk := &compute.AttachedDisk{
Expand All @@ -234,6 +308,7 @@ func (DiskHandler *GCPDiskHandler) AttachDisk(diskIID irs.IID, ownerVM irs.IID)

WaitOperationComplete(DiskHandler.Client, projectID, region, zone, op.Name, 3)

// attach가 끝나면 disk정보 return
diskInfo, errDiskInfo := DiskHandler.GetDisk(diskIID)
if errDiskInfo != nil {
cblogger.Error(errDiskInfo)
Expand Down Expand Up @@ -429,6 +504,14 @@ func convertDiskInfo(diskResp *compute.Disk) (irs.DiskInfo, error) {
diskInfo.IId = irs.IID{NameId: diskResp.Name, SystemId: diskResp.Name}
diskInfo.DiskSize = strconv.FormatInt(diskResp.SizeGb, 10)
diskInfo.CreatedTime, _ = time.Parse(time.RFC3339, diskResp.CreationTimestamp)
//diskInfo.Zone = diskResp.Zone // diskResp의 zone은 url 형태이므로 zone 만 추출
index := strings.Index(diskResp.Zone, "zones/") // "zones/"의 인덱스를 찾음
if index != -1 {
diskInfo.Zone = diskResp.Zone[index+len("zones/"):] // "zones/" 다음의 문자열을 추출
}else{
diskInfo.Zone = diskResp.Zone
}


// Users : the users of the disk (attached instances)
if diskResp.Users != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type GCPVPCHandler struct {
}

//@TODO : VPC 생성 로직 변경 필요 / 서브넷이 백그라운드로 생성되기 때문에 조회 시 모두 생성될 때까지 대기하는 로직 필요(그렇지 않으면 일부 정보가 누락됨)
// #1067 : gcp는 subnet 생성시 zone을 사용하지 않음.
func (vVPCHandler *GCPVPCHandler) CreateVPC(vpcReqInfo irs.VPCReqInfo) (irs.VPCInfo, error) {
cblogger.Info(vpcReqInfo)

Expand Down Expand Up @@ -141,7 +142,7 @@ func (vVPCHandler *GCPVPCHandler) CreateVPC(vpcReqInfo irs.VPCReqInfo) (irs.VPCI
return irs.VPCInfo{}, errors.New("Making Subnet Error - " + subnetName)
}

spew.Dump(infoSubnet)
//spew.Dump(infoSubnet)
//생성된 서브넷이 조회되는데 시간이 필요하기 때문에 홀딩 함.
/*
errChkSubnetStatus := vVPCHandler.WaitForRunSubnet(subnetName, true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (cloudConn *TencentCloudConnection) CreateKeyPairHandler() (irs.KeyPairHand
func (cloudConn *TencentCloudConnection) CreateVMHandler() (irs.VMHandler, error) {
cblogger.Info("Start CreateVMHandler()")

vmHandler := trs.TencentVMHandler{Region: cloudConn.Region, Client: cloudConn.VMClient, DiskClient: cloudConn.DiskClient}
vmHandler := trs.TencentVMHandler{Region: cloudConn.Region, Client: cloudConn.VMClient, DiskClient: cloudConn.DiskClient, VPCClient: cloudConn.VNetworkClient}
return &vmHandler, nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ package resources
import (
"errors"
"time"
"strconv"

call "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/call-log"
irs "github.com/cloud-barista/cb-spider/cloud-control-manager/cloud-driver/interfaces/resources"

cbs "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs/v20170312"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
vpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312"

tencentError "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
)
Expand Down Expand Up @@ -281,3 +284,77 @@ func DescribeZones(client *cvm.Client) (*cvm.DescribeZonesResponse, error) {

return responseZones, nil
}

// subnet 목록 조회 by vpc
func ListSubnet(client *vpc.Client, reqVpcId string) ([]irs.SubnetInfo, error){
cblogger.Infof("reqVpcId : [%s]", reqVpcId)
var arrSubnetInfoList []irs.SubnetInfo

// logger for HisCall
callogger := call.GetLogger("HISCALL")
callLogInfo := call.CLOUDLOGSCHEMA{
CloudOS: call.TENCENT,
RegionZone: client.GetRegion(),
ResourceType: call.VPCSUBNET,
ResourceName: "ListSubnet - VpcId:" + reqVpcId,
CloudOSAPI: "DescribeSubnets()",
ElapsedTime: "",
ErrorMSG: "",
}

request := vpc.NewDescribeSubnetsRequest()
request.Filters = []*vpc.Filter{
&vpc.Filter{
Name: common.StringPtr("vpc-id"),
Values: common.StringPtrs([]string{reqVpcId}),
},
}

callLogStart := call.Start()
response, err := client.DescribeSubnets(request)
callLogInfo.ElapsedTime = call.Elapsed(callLogStart)
callogger.Info(call.String(callLogInfo))
if err != nil {
cblogger.Error(err)
return nil, err
}

for _, curSubnet := range response.Response.SubnetSet {
cblogger.Infof("[%s] Check Subnet Information", *curSubnet.SubnetId)
resSubnetInfo := irs.SubnetInfo{
IId: irs.IID{SystemId: *curSubnet.SubnetId, NameId: *curSubnet.SubnetName},
IPv4_CIDR: *curSubnet.CidrBlock,
Zone: *curSubnet.Zone,
//Status: *subnetInfo.State,
}

keyValueList := []irs.KeyValue{
{Key: "VpcId", Value: *curSubnet.VpcId},
{Key: "IsDefault", Value: strconv.FormatBool(*curSubnet.IsDefault)},
{Key: "AvailabilityZone", Value: *curSubnet.Zone},
}
resSubnetInfo.KeyValueList = keyValueList
arrSubnetInfoList = append(arrSubnetInfoList, resSubnetInfo)
}

return arrSubnetInfoList, nil
}

// subnet 단건 조회
func GetSubnet(client *vpc.Client, reqVpcId string, reqSubnetId string) (irs.SubnetInfo, error){
resultSubnetInfo := irs.SubnetInfo{}
subnetList, err := ListSubnet(client, reqVpcId)
if err != nil {
return resultSubnetInfo, err
}


for _, curSubnet := range subnetList {
if curSubnet.IId.SystemId == reqSubnetId {
return curSubnet, nil
}
}

// 못찾으면 not found error
return resultSubnetInfo, errors.New("cannot find the subnet")
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,14 @@ func (DiskHandler *TencentDiskHandler) CreateDisk(diskReqInfo irs.DiskInfo) (irs
return irs.DiskInfo{}, errors.New("A disk with the name " + diskReqInfo.IId.NameId + " already exists.")
}

// region base이므로 특정 zone을 지정시 해당 zone에 생성.
zone := DiskHandler.Region.Zone
if diskReqInfo.Zone != ""{
zone = diskReqInfo.Zone
}

request := cbs.NewCreateDisksRequest()
request.Placement = &cbs.Placement{Zone: common.StringPtr(DiskHandler.Region.Zone)}
request.Placement = &cbs.Placement{Zone: common.StringPtr(zone)}
request.DiskChargeType = common.StringPtr("POSTPAID_BY_HOUR")

diskErr := validateDisk(&diskReqInfo)
Expand Down Expand Up @@ -251,6 +257,7 @@ func convertDiskInfo(diskResp *cbs.Disk) (irs.DiskInfo, error) {
diskInfo.OwnerVM.SystemId = *diskResp.InstanceId
diskInfo.CreatedTime, _ = time.Parse("2006-01-02 15:04:05", *diskResp.CreateTime)
diskInfo.Status = convertTenStatusToDiskStatus(diskResp)
diskInfo.Zone = *diskResp.Placement.Zone

return diskInfo, nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@ import (
tencentcbs "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs/v20170312"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
tencentvpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312"
//lighthouse "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/lighthouse/v20200324"
)

type TencentVMHandler struct {
Region idrv.RegionInfo
Client *cvm.Client
DiskClient *tencentcbs.Client
VPCClient *tencentvpc.Client
}
//Client *vpc.Client

//type TencentCbsHandler struct {
// Region idrv.RegionInfo
Expand Down Expand Up @@ -68,8 +71,19 @@ type TencentVMHandler struct {
// VM생성 시 Zone이 필수라서 Credential의 Zone에만 생성함.
func (vmHandler *TencentVMHandler) StartVM(vmReqInfo irs.VMReqInfo) (irs.VMInfo, error) {
cblogger.Info(vmReqInfo)

zoneId := vmHandler.Region.Zone

vpcHandler := TencentVPCHandler{
Region: vmHandler.Region,
Client: vmHandler.VPCClient,
}
subnetInfo, err := GetSubnet(vpcHandler.Client, vmReqInfo.VpcIID.SystemId, vmReqInfo.SubnetIID.SystemId)
if err != nil {
return irs.VMInfo{}, errors.New("there is no available subnet")
}
if subnetInfo.Zone != "" {
zoneId = subnetInfo.Zone
}
cblogger.Debugf("Zone : %s", zoneId)
if zoneId == "" {
cblogger.Error("Connection information does not contain Zone information.")
Expand Down Expand Up @@ -194,8 +208,9 @@ func (vmHandler *TencentVMHandler) StartVM(vmReqInfo irs.VMReqInfo) (irs.VMInfo,
//=============================
// Placement 처리
//=============================
// 이슈 #1097 : placement는 optional이며 vm생성시 subnet은 1개만 선택하므로 subnet에 정의된 zone 사용하도록. (subnet에서 선택할 zone과 다른 zone에 생성불가)
request.Placement = &cvm.Placement{
Zone: common.StringPtr(vmHandler.Region.Zone),
Zone: common.StringPtr(zoneId),
}

/* 이슈 #348에 의해 RootDisk 기능 지원하면서 기존 로직 제거
Expand Down
Loading

0 comments on commit 4834183

Please sign in to comment.