Skip to content

Commit 2bc8d55

Browse files
authored
Merge pull request #1581 from powerkimhub/fix/gcp-vpc-subnet-cannot-delete
[GCP] Fix VPC/Subnet deletion failure and improve AddSubnet error handling
2 parents d1c6d51 + 09effbd commit 2bc8d55

File tree

1 file changed

+54
-20
lines changed
  • cloud-control-manager/cloud-driver/drivers/gcp/resources

1 file changed

+54
-20
lines changed

cloud-control-manager/cloud-driver/drivers/gcp/resources/VPCHandler.go

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ package resources
1414
import (
1515
"context"
1616
"errors"
17+
"fmt"
1718
"strconv"
1819
"strings"
1920

@@ -339,6 +340,22 @@ func (vVPCHandler *GCPVPCHandler) WaitUntilComplete(resourceId string, isGlobalA
339340
//PENDING, RUNNING, or DONE.
340341
//if (opSatus.Status == "RUNNING" || opSatus.Status == "DONE") && opSatus.Progress >= 100 {
341342
if opSatus.Status == "DONE" {
343+
// Check if the operation completed with errors
344+
if opSatus.Error != nil {
345+
if opSatus.Error.Errors != nil {
346+
for _, errDetail := range opSatus.Error.Errors {
347+
// Check for CIDR conflict-related errors
348+
errMsg := strings.ToLower(errDetail.Message)
349+
if strings.Contains(errMsg, "overlap") || strings.Contains(errMsg, "conflict") ||
350+
strings.Contains(errMsg, "range") || strings.Contains(errMsg, "cidr") ||
351+
strings.Contains(errMsg, "address") || strings.Contains(errMsg, "invalid") {
352+
return fmt.Errorf("CIDR conflict detected in operation: %s - %s", errDetail.Code, errDetail.Message)
353+
}
354+
}
355+
}
356+
// Return general operation error
357+
return fmt.Errorf("operation failed: %v", opSatus.Error)
358+
}
342359
cblogger.Info("The request has been processed successfully, so the wait is terminated.")
343360
return nil
344361
}
@@ -386,19 +403,36 @@ func (vVPCHandler *GCPVPCHandler) ListVPC() ([]*irs.VPCInfo, error) {
386403
var vpcInfo []*irs.VPCInfo
387404

388405
for _, item := range vpcList.Items {
389-
iId := irs.IID{
390-
NameId: item.Name,
391-
//SystemId: strconv.FormatUint(item.Id, 10),
392-
SystemId: item.Name,
393-
}
394-
subnetInfo, err := vVPCHandler.GetVPC(iId)
395-
if err != nil {
396-
cblogger.Error(err)
397-
return vpcInfo, err
406+
// Use Networks.List() result directly instead of calling GetVPC()
407+
subnetInfoList := []irs.SubnetInfo{}
408+
409+
// Get subnet information if subnets exist
410+
if item.Subnetworks != nil {
411+
for _, subnetURL := range item.Subnetworks {
412+
str := strings.Split(subnetURL, "/")
413+
region := str[len(str)-3]
414+
subnet := str[len(str)-1]
415+
infoSubnet, err := vVPCHandler.Client.Subnetworks.Get(projectID, region, subnet).Do()
416+
if err != nil {
417+
cblogger.Error(err)
418+
return vpcInfo, err
419+
}
420+
subnetInfoList = append(subnetInfoList, mappingSubnet(infoSubnet))
421+
}
398422
}
399423

400-
vpcInfo = append(vpcInfo, &subnetInfo)
424+
networkInfo := irs.VPCInfo{
425+
IId: irs.IID{
426+
NameId: item.Name,
427+
SystemId: item.Name,
428+
},
429+
IPv4_CIDR: "GCP VPC does not support IPv4_CIDR",
430+
SubnetInfoList: subnetInfoList,
431+
}
432+
// Use StructToKeyValueList for VPC metadata
433+
networkInfo.KeyValueList = irs.StructToKeyValueList(item)
401434

435+
vpcInfo = append(vpcInfo, &networkInfo)
402436
}
403437

404438
return vpcInfo, nil
@@ -479,8 +513,8 @@ func mappingSubnet(subnet *compute.Subnetwork) irs.SubnetInfo {
479513
//str := subnet.SelfLink
480514
//str := strings.Split(subnet.SelfLink, "/")
481515
//subnetName := str[len(str)-1]
482-
//regionStr := strings.Split(subnet.Region, "/")
483-
//region := regionStr[len(regionStr)-1]
516+
regionStr := strings.Split(subnet.Region, "/")
517+
region := regionStr[len(regionStr)-1]
484518
subnetInfo := irs.SubnetInfo{
485519
IId: irs.IID{
486520
NameId: subnet.Name,
@@ -496,6 +530,11 @@ func mappingSubnet(subnet *compute.Subnetwork) irs.SubnetInfo {
496530

497531
// 2025-03-13 StructToKeyValueList 사용으로 변경
498532
subnetInfo.KeyValueList = irs.StructToKeyValueList(subnet)
533+
534+
// Add region and subnet information for DeleteVPC functionality
535+
subnetInfo.KeyValueList = append(subnetInfo.KeyValueList, irs.KeyValue{Key: "region", Value: region})
536+
subnetInfo.KeyValueList = append(subnetInfo.KeyValueList, irs.KeyValue{Key: "subnet", Value: subnet.Name})
537+
499538
return subnetInfo
500539
}
501540

@@ -581,13 +620,13 @@ func (vVPCHandler *GCPVPCHandler) DeleteVPC(vpcID irs.IID) (bool, error) {
581620
}
582621
*/
583622

584-
cblogger.Infof("Waiting for [%s] VPC to be finally deleted - Resource ID: [%d]", name)
623+
cblogger.Infof("Waiting for [%s] VPC to be finally deleted - Resource ID: [%d]", name, info.Id)
585624
errChkVpcStatus := vVPCHandler.WaitUntilComplete(strconv.FormatUint(info.Id, 10), true)
586625
callogger.Info(call.String(callLogInfo))
587626
if errChkVpcStatus != nil {
588627
callLogInfo.ErrorMSG = errChkVpcStatus.Error()
589628
callogger.Info(call.String(callLogInfo))
590-
cblogger.Errorf("[%s] Subnet deletion completion wait failed", name)
629+
cblogger.Errorf("[%s] VPC deletion completion wait failed", name)
591630
cblogger.Error(errChkVpcStatus)
592631
return false, errChkVpcStatus
593632
}
@@ -597,17 +636,12 @@ func (vVPCHandler *GCPVPCHandler) DeleteVPC(vpcID irs.IID) (bool, error) {
597636
}
598637

599638
func (VPCHandler *GCPVPCHandler) AddSubnet(vpcIID irs.IID, subnetInfo irs.SubnetInfo) (irs.VPCInfo, error) {
600-
cblogger.Infof("[%s] Subnet added - CIDR: %s", subnetInfo.IId.NameId, subnetInfo.IPv4_CIDR)
601-
//resSubnet, errSubnet := VPCHandler.CreateSubnet(vpcIID.SystemId, subnetInfo)
602639
_, errSubnet := VPCHandler.CreateSubnet(vpcIID.SystemId, subnetInfo)
603640
if errSubnet != nil {
604-
cblogger.Error(errSubnet)
605641
return irs.VPCInfo{}, errSubnet
606642
}
607-
//cblogger.Debug(resSubnet)
608643

609644
return VPCHandler.GetVPC(vpcIID)
610-
//return irs.VPCInfo{}, nil
611645
}
612646

613647
// 리턴 값은 구현하지 않고 nil을 리턴함. - 현재 사용되는 곳이 없어서 시간상 누락 시킴.
@@ -637,7 +671,7 @@ func (vVPCHandler *GCPVPCHandler) CreateSubnet(vpcId string, reqSubnetInfo irs.S
637671
checkInfo, err := vVPCHandler.Client.Subnetworks.Get(projectID, region, subnetName).Do()
638672
callLogInfo.ElapsedTime = call.Elapsed(callLogStart)
639673
if err == nil {
640-
callLogInfo.ErrorMSG = err.Error()
674+
callLogInfo.ErrorMSG = "Subnet already exists"
641675
cblogger.Errorf("[%s] Subnet already exists ", subnetName)
642676
callogger.Info(call.String(callLogInfo))
643677
return irs.SubnetInfo{}, errors.New("Already Exist - " + subnetName + " Subnet is exist")

0 commit comments

Comments
 (0)