From c04c94f23ba002382966fb315992b3107146eedc Mon Sep 17 00:00:00 2001 From: Dharaneeshwaran Ravichandran Date: Wed, 15 May 2024 14:52:57 +0530 Subject: [PATCH] Use local routing in transit gateway when PowerVS and VPC are from same region --- api/v1beta2/ibmpowervscluster_types.go | 3 ++ api/v1beta2/zz_generated.deepcopy.go | 5 +++ cloud/scope/powervs_cluster.go | 45 ++++++++++++------- ...e.cluster.x-k8s.io_ibmpowervsclusters.yaml | 4 ++ ...r.x-k8s.io_ibmpowervsclustertemplates.yaml | 4 ++ util/util.go | 8 ++++ 6 files changed, 54 insertions(+), 15 deletions(-) diff --git a/api/v1beta2/ibmpowervscluster_types.go b/api/v1beta2/ibmpowervscluster_types.go index 65efbf5cd..15c0942da 100644 --- a/api/v1beta2/ibmpowervscluster_types.go +++ b/api/v1beta2/ibmpowervscluster_types.go @@ -251,6 +251,9 @@ type TransitGateway struct { // id of resource. // +optional ID *string `json:"id,omitempty"` + // globalRouting indicates whether to set global routing true or not while creating the transit gateway. + // +optional + GlobalRouting *bool `json:"globalRouting,omitempty"` } // VPCResourceReference is a reference to a specific VPC resource by ID or Name diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index 20a61a028..5171d98b6 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -1518,6 +1518,11 @@ func (in *TransitGateway) DeepCopyInto(out *TransitGateway) { *out = new(string) **out = **in } + if in.GlobalRouting != nil { + in, out := &in.GlobalRouting, &out.GlobalRouting + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TransitGateway. diff --git a/cloud/scope/powervs_cluster.go b/cloud/scope/powervs_cluster.go index b1a1160b0..dea73669e 100644 --- a/cloud/scope/powervs_cluster.go +++ b/cloud/scope/powervs_cluster.go @@ -1334,16 +1334,26 @@ func (s *PowerVSClusterScope) createTransitGateway() (*string, error) { return nil, fmt.Errorf("error getting resource group id for resource group %v, id is empty", s.ResourceGroup()) } - vpcRegion := s.getVPCRegion() - if vpcRegion == nil { - return nil, fmt.Errorf("failed to get vpc region") + location, globalRouting := s.getTransitGatewayLocationAndRouting() + if location == nil { + return nil, fmt.Errorf("failed to get transit gateway location") } + // throw error when user tries to use local routing where global routing is required. + if s.IBMPowerVSCluster.Spec.TransitGateway.GlobalRouting != nil && !*s.IBMPowerVSCluster.Spec.TransitGateway.GlobalRouting && *globalRouting { + return nil, fmt.Errorf("failed to use local routing for transit gateway since powervs and vpc region used requires global routing") + } + // setting global routing to true when it is set by user. + if s.IBMPowerVSCluster.Spec.TransitGateway.GlobalRouting != nil && *s.IBMPowerVSCluster.Spec.TransitGateway.GlobalRouting && !*globalRouting { + globalRouting = ptr.To(true) + } + + s.TransitGatewayClient.ListSupportedTransitGatewayLocations() tgName := s.GetServiceName(infrav1beta2.ResourceTypeTransitGateway) tg, _, err := s.TransitGatewayClient.CreateTransitGateway(&tgapiv1.CreateTransitGatewayOptions{ - Location: vpcRegion, + Location: location, Name: tgName, - Global: ptr.To(true), + Global: globalRouting, ResourceGroup: &tgapiv1.ResourceGroupIdentity{ID: ptr.To(resourceGroupID)}, }) if err != nil { @@ -1744,24 +1754,29 @@ func (s *PowerVSClusterScope) fetchResourceGroupID() (string, error) { return "", err } -// getVPCRegion returns region associated with VPC zone. -func (s *PowerVSClusterScope) getVPCRegion() *string { - if s.IBMPowerVSCluster.Spec.VPC != nil { - return s.IBMPowerVSCluster.Spec.VPC.Region - } - // if vpc region is not set try to fetch corresponding region from power vs zone +// getTransitGatewayLocationAndRouting returns appropriate location and routing suitable for transit gateway. +// routing indicates whether to enable global routing on transit gateway or not. +// returns true when powervs and vpc region are not common otherwise false. +func (s *PowerVSClusterScope) getTransitGatewayLocationAndRouting() (*string, *bool) { zone := s.Zone() if zone == nil { s.Info("powervs zone is not set") - return nil + return nil, nil } region := endpoints.ConstructRegionFromZone(*zone) - vpcRegion, err := genUtil.VPCRegionForPowerVSRegion(region) + + if s.IBMPowerVSCluster.Spec.VPC != nil { + routing := !genUtil.IsCommonPowerVSAndVPCRegion(region, *s.IBMPowerVSCluster.Spec.VPC.Region) + return s.IBMPowerVSCluster.Spec.VPC.Region, &routing + } + location, err := genUtil.VPCRegionForPowerVSRegion(region) if err != nil { s.Error(err, fmt.Sprintf("failed to fetch vpc region associated with powervs region %s", region)) - return nil + return nil, nil } - return &vpcRegion + + routing := !genUtil.IsCommonPowerVSAndVPCRegion(region, *s.IBMPowerVSCluster.Spec.VPC.Region) + return &location, &routing } // fetchVPCCRN returns VPC CRN. diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmpowervsclusters.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmpowervsclusters.yaml index ad94420e4..f5a94669b 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmpowervsclusters.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmpowervsclusters.yaml @@ -396,6 +396,10 @@ spec: when TransitGateway.ID is set, its expected that there exist a TransitGateway with ID or else system will give error. when TransitGateway.Name is set, system will first check for TransitGateway with Name, if not exist system will create new TransitGateway. properties: + globalRouting: + description: globalRouting indicates whether to set global routing + true or not while creating the transit gateway. + type: boolean id: description: id of resource. type: string diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmpowervsclustertemplates.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmpowervsclustertemplates.yaml index fa43d3519..dc4dbac0a 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmpowervsclustertemplates.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_ibmpowervsclustertemplates.yaml @@ -427,6 +427,10 @@ spec: when TransitGateway.ID is set, its expected that there exist a TransitGateway with ID or else system will give error. when TransitGateway.Name is set, system will first check for TransitGateway with Name, if not exist system will create new TransitGateway. properties: + globalRouting: + description: globalRouting indicates whether to set global + routing true or not while creating the transit gateway. + type: boolean id: description: id of resource. type: string diff --git a/util/util.go b/util/util.go index deb85d576..688fdcd91 100644 --- a/util/util.go +++ b/util/util.go @@ -197,3 +197,11 @@ func VPCZonesForPowerVSRegion(region string) ([]string, error) { } return nil, fmt.Errorf("VPC zones corresponding to a PowerVS region %s not found ", region) } + +// IsCommonPowerVSAndVPCRegion returns true when powervs and vpc belongs to a common region. +func IsCommonPowerVSAndVPCRegion(powerVSRegion string, vpcRegion string) bool { + if r, ok := Regions[powerVSRegion]; ok && r.VPCRegion == vpcRegion { + return true + } + return false +}