Skip to content

Commit 4b22609

Browse files
Merge pull request #7592 from miyamotoh/transit-gateway-quota
MULTIARCH-4042: Reuse existing Transit Gateway in target Workspace, or create anew
2 parents 528887f + 0e97f27 commit 4b22609

File tree

8 files changed

+318
-132
lines changed

8 files changed

+318
-132
lines changed

data/data/powervs/cluster/main.tf

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,13 @@ module "pi_network" {
3535
}
3636
source = "./power_network"
3737

38-
cluster_id = var.cluster_id
39-
cloud_instance_id = module.iaas.si_guid
40-
resource_group = var.powervs_resource_group
41-
machine_cidr = var.machine_v4_cidrs[0]
42-
vpc_crn = module.vpc.vpc_crn
43-
dns_server = module.dns.dns_server
44-
enable_snat = var.powervs_enable_snat
45-
transit_gateway_enabled = var.powervs_transit_gateway_enabled
38+
cluster_id = var.cluster_id
39+
cloud_instance_id = module.iaas.si_guid
40+
resource_group = var.powervs_resource_group
41+
machine_cidr = var.machine_v4_cidrs[0]
42+
vpc_crn = module.vpc.vpc_crn
43+
dns_server = module.dns.dns_server
44+
enable_snat = var.powervs_enable_snat
4645
}
4746

4847
resource "ibm_pi_key" "cluster_key" {
@@ -148,12 +147,13 @@ module "transit_gateway" {
148147
}
149148
source = "./transit_gateway"
150149

151-
cluster_id = var.cluster_id
152-
resource_group = var.powervs_resource_group
153-
service_instance_crn = module.iaas.si_crn
154-
transit_gateway_enabled = var.powervs_transit_gateway_enabled
155-
vpc_crn = module.vpc.vpc_crn
156-
vpc_region = var.powervs_vpc_region
150+
cluster_id = var.cluster_id
151+
resource_group = var.powervs_resource_group
152+
service_instance_crn = module.iaas.si_crn
153+
attached_transit_gateway = var.powervs_attached_transit_gateway
154+
tg_connection_vpc_id = var.powervs_tg_connection_vpc_id
155+
vpc_crn = module.vpc.vpc_crn
156+
vpc_region = var.powervs_vpc_region
157157
}
158158

159159
module "iaas" {

data/data/powervs/cluster/transit_gateway/transit_gateway.tf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/tg_gateway
22
resource "ibm_tg_gateway" "transit_gateway" {
3-
count = var.transit_gateway_enabled ? 1 : 0
3+
count = var.attached_transit_gateway == "" ? 1 : 0
44
name = "tg-${var.cluster_id}"
55
location = var.vpc_region
66
global = true
@@ -14,16 +14,16 @@ data "ibm_resource_group" "rg_pvs_ipi_rg" {
1414

1515
# https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/tg_connection
1616
resource "ibm_tg_connection" "tg_connection_vpc" {
17-
count = var.transit_gateway_enabled ? 1 : 0
18-
gateway = resource.ibm_tg_gateway.transit_gateway[count.index].id
17+
count = var.tg_connection_vpc_id == "" ? 1 : 0
18+
gateway = var.attached_transit_gateway == "" ? resource.ibm_tg_gateway.transit_gateway[0].id : var.attached_transit_gateway
1919
network_type = "vpc"
2020
name = "tg-${var.cluster_id}-conn-vpc"
2121
network_id = var.vpc_crn
2222
}
2323

2424
# https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/tg_connection
2525
resource "ibm_tg_connection" "tg_connection_pvs" {
26-
count = var.transit_gateway_enabled ? 1 : 0
26+
count = var.attached_transit_gateway == "" ? 1 : 0
2727
gateway = resource.ibm_tg_gateway.transit_gateway[count.index].id
2828
network_type = "power_virtual_server"
2929
name = "tg-${var.cluster_id}-conn-pvs"

data/data/powervs/cluster/transit_gateway/variables.tf

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@ variable "resource_group" {
88
description = "The name of the Power VS resource group to which the user belongs."
99
}
1010

11-
variable "transit_gateway_enabled" {
12-
type = bool
13-
description = "Boolean indicating if Transit Gateways should be used."
14-
default = false
11+
variable "attached_transit_gateway" {
12+
type = string
13+
description = "The ID of already attached Transit Gateways, if any."
14+
}
15+
16+
variable "tg_connection_vpc_id" {
17+
type = string
18+
description = "ID of a VPC connection to the transit gateway specified in attached_transit_gateway, if any."
1519
}
1620

1721
variable "service_instance_crn" {

data/data/powervs/variables-powervs.tf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ variable "powervs_vpc_gateway_attached" {
9393
default = false
9494
}
9595

96+
variable "powervs_tg_connection_vpc_id" {
97+
type = string
98+
description = "ID of a VPC connection to the transit gateway specified in attached_transit_gateway, if any."
99+
}
100+
96101
variable "powervs_vpc_gateway_name" {
97102
type = string
98103
description = "The name of a pre-created VPC gateway. Must be in $powervs_vpc_region"
@@ -117,6 +122,12 @@ variable "powervs_transit_gateway_enabled" {
117122
default = false
118123
}
119124

125+
variable "powervs_attached_transit_gateway" {
126+
type = string
127+
description = "ID of already attached Transit Gateways."
128+
default = ""
129+
}
130+
120131
################################################################
121132
# Configure instances
122133
################################################################

pkg/asset/cluster/tfvars.go

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -895,10 +895,10 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error {
895895
}
896896
var (
897897
vpcRegion, vpcZone string
898+
vpc *vpcv1.VPC
898899
)
899900
vpcName := installConfig.Config.PowerVS.VPCName
900901
if vpcName != "" {
901-
var vpc *vpcv1.VPC
902902
vpc, err = client.GetVPCByName(ctx, vpcName)
903903
if err != nil {
904904
return err
@@ -940,7 +940,20 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error {
940940
}
941941
}
942942

943-
transitGatewayEnabled := powervsconfig.TransitGatewayEnabledZone(installConfig.Config.Platform.PowerVS.Zone)
943+
attachedTG := ""
944+
tgConnectionVPCID := ""
945+
if installConfig.Config.PowerVS.ServiceInstanceGUID != "" {
946+
attachedTG, err = client.GetAttachedTransitGateway(ctx, installConfig.Config.PowerVS.ServiceInstanceGUID)
947+
if err != nil {
948+
return err
949+
}
950+
if attachedTG != "" && vpc != nil {
951+
tgConnectionVPCID, err = client.GetTGConnectionVPC(ctx, attachedTG, *vpc.ID)
952+
if err != nil {
953+
return err
954+
}
955+
}
956+
}
944957

945958
// If a service instance GUID was passed in the install-config.yaml file, then
946959
// find the corresponding name for it. Otherwise, we expect our Terraform to
@@ -953,27 +966,28 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error {
953966
osImage := strings.SplitN(string(*rhcosImage), "/", 2)
954967
data, err = powervstfvars.TFVars(
955968
powervstfvars.TFVarsSources{
956-
MasterConfigs: masterConfigs,
957-
Region: installConfig.Config.Platform.PowerVS.Region,
958-
Zone: installConfig.Config.Platform.PowerVS.Zone,
959-
APIKey: APIKey,
960-
SSHKey: installConfig.Config.SSHKey,
961-
PowerVSResourceGroup: installConfig.Config.PowerVS.PowerVSResourceGroup,
962-
ImageBucketName: osImage[0],
963-
ImageBucketFileName: osImage[1],
964-
VPCRegion: vpcRegion,
965-
VPCZone: vpcZone,
966-
VPCName: vpcName,
967-
VPCSubnetName: vpcSubnet,
968-
VPCPermitted: vpcPermitted,
969-
VPCGatewayName: vpcGatewayName,
970-
VPCGatewayAttached: vpcGatewayAttached,
971-
CISInstanceCRN: cisCRN,
972-
DNSInstanceCRN: dnsCRN,
973-
PublishStrategy: installConfig.Config.Publish,
974-
EnableSNAT: len(installConfig.Config.DeprecatedImageContentSources) == 0 && len(installConfig.Config.ImageDigestSources) == 0,
975-
TransitGatewayEnabled: transitGatewayEnabled,
976-
ServiceInstanceName: serviceInstanceName,
969+
MasterConfigs: masterConfigs,
970+
Region: installConfig.Config.Platform.PowerVS.Region,
971+
Zone: installConfig.Config.Platform.PowerVS.Zone,
972+
APIKey: APIKey,
973+
SSHKey: installConfig.Config.SSHKey,
974+
PowerVSResourceGroup: installConfig.Config.PowerVS.PowerVSResourceGroup,
975+
ImageBucketName: osImage[0],
976+
ImageBucketFileName: osImage[1],
977+
VPCRegion: vpcRegion,
978+
VPCZone: vpcZone,
979+
VPCName: vpcName,
980+
VPCSubnetName: vpcSubnet,
981+
VPCPermitted: vpcPermitted,
982+
VPCGatewayName: vpcGatewayName,
983+
VPCGatewayAttached: vpcGatewayAttached,
984+
CISInstanceCRN: cisCRN,
985+
DNSInstanceCRN: dnsCRN,
986+
PublishStrategy: installConfig.Config.Publish,
987+
EnableSNAT: len(installConfig.Config.DeprecatedImageContentSources) == 0 && len(installConfig.Config.ImageDigestSources) == 0,
988+
AttachedTransitGateway: attachedTG,
989+
TGConnectionVPCID: tgConnectionVPCID,
990+
ServiceInstanceName: serviceInstanceName,
977991
},
978992
)
979993
if err != nil {

pkg/asset/installconfig/powervs/client.go

Lines changed: 136 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"fmt"
77
"net/http"
8+
"strings"
89
"time"
910

1011
"github.com/IBM-Cloud/bluemix-go/crn"
@@ -14,6 +15,7 @@ import (
1415
"github.com/IBM/networking-go-sdk/dnssvcsv1"
1516
"github.com/IBM/networking-go-sdk/dnszonesv1"
1617
"github.com/IBM/networking-go-sdk/resourcerecordsv1"
18+
"github.com/IBM/networking-go-sdk/transitgatewayapisv1"
1719
"github.com/IBM/networking-go-sdk/zonesv1"
1820
"github.com/IBM/platform-services-go-sdk/iamidentityv1"
1921
"github.com/IBM/platform-services-go-sdk/resourcecontrollerv2"
@@ -42,16 +44,19 @@ type API interface {
4244
ListServiceInstances(ctx context.Context) ([]string, error)
4345
ServiceInstanceGUIDToName(ctx context.Context, id string) (string, error)
4446
GetDatacenterCapabilities(ctx context.Context, region string) (map[string]bool, error)
47+
GetAttachedTransitGateway(ctx context.Context, svcInsID string) (string, error)
48+
GetTGConnectionVPC(ctx context.Context, gatewayID string, vpcSubnetID string) (string, error)
4549
}
4650

4751
// Client makes calls to the PowerVS API.
4852
type Client struct {
49-
APIKey string
50-
BXCli *BxClient
51-
managementAPI *resourcemanagerv2.ResourceManagerV2
52-
controllerAPI *resourcecontrollerv2.ResourceControllerV2
53-
vpcAPI *vpcv1.VpcV1
54-
dnsServicesAPI *dnssvcsv1.DnsSvcsV1
53+
APIKey string
54+
BXCli *BxClient
55+
managementAPI *resourcemanagerv2.ResourceManagerV2
56+
controllerAPI *resourcecontrollerv2.ResourceControllerV2
57+
vpcAPI *vpcv1.VpcV1
58+
dnsServicesAPI *dnssvcsv1.DnsSvcsV1
59+
transitGatewayAPI *transitgatewayapisv1.TransitGatewayApisV1
5560
}
5661

5762
// cisServiceID is the Cloud Internet Services' catalog service ID.
@@ -138,6 +143,7 @@ func (c *Client) loadSDKServices() error {
138143
c.loadResourceControllerAPI,
139144
c.loadVPCV1API,
140145
c.loadDNSServicesAPI,
146+
c.loadTransitGatewayAPI,
141147
}
142148

143149
// Call all the load functions.
@@ -504,6 +510,22 @@ func (c *Client) loadDNSServicesAPI() error {
504510
return nil
505511
}
506512

513+
func (c *Client) loadTransitGatewayAPI() error {
514+
authenticator := &core.IamAuthenticator{
515+
ApiKey: c.APIKey,
516+
}
517+
versionDate := "2023-07-04"
518+
tgSvc, err := transitgatewayapisv1.NewTransitGatewayApisV1(&transitgatewayapisv1.TransitGatewayApisV1Options{
519+
Authenticator: authenticator,
520+
Version: &versionDate,
521+
})
522+
if err != nil {
523+
return err
524+
}
525+
c.transitGatewayAPI = tgSvc
526+
return nil
527+
}
528+
507529
// SetVPCServiceURLForRegion will set the VPC Service URL to a specific IBM Cloud Region, in order to access Region scoped resources
508530
func (c *Client) SetVPCServiceURLForRegion(ctx context.Context, region string) error {
509531
regionOptions := c.vpcAPI.NewGetRegionOptions(region)
@@ -663,12 +685,6 @@ func (c *Client) ListServiceInstances(ctx context.Context) ([]string, error) {
663685
return serviceInstances, nil
664686
}
665687

666-
// TransitGatewayEnabledZone returns if a zone is configured for transit gateways rather than cloud connections.
667-
func TransitGatewayEnabledZone(zone string) bool {
668-
// @TBD - HACK. Waiting for officially supported detection function
669-
return zone == "dal10"
670-
}
671-
672688
// ServiceInstanceGUIDToName returns the name of the matching service instance GUID which was passed in.
673689
func (c *Client) ServiceInstanceGUIDToName(ctx context.Context, id string) (string, error) {
674690
var (
@@ -765,3 +781,111 @@ func (c *Client) GetDatacenterCapabilities(ctx context.Context, region string) (
765781
}
766782
return getOk.Payload.Capabilities, nil
767783
}
784+
785+
// GetAttachedTransitGateway finds an existing Transit Gateway attached to the provided PowerVS cloud instance.
786+
func (c *Client) GetAttachedTransitGateway(ctx context.Context, svcInsID string) (string, error) {
787+
var (
788+
gateways []transitgatewayapisv1.TransitGateway
789+
gateway transitgatewayapisv1.TransitGateway
790+
err error
791+
conns []transitgatewayapisv1.TransitConnection
792+
conn transitgatewayapisv1.TransitConnection
793+
)
794+
gateways, err = c.getTransitGateways(ctx)
795+
if err != nil {
796+
return "", err
797+
}
798+
for _, gateway = range gateways {
799+
conns, err = c.getTransitConnections(ctx, *gateway.ID)
800+
if err != nil {
801+
return "", err
802+
}
803+
for _, conn = range conns {
804+
if *conn.NetworkType == "power_virtual_server" && strings.Contains(*conn.NetworkID, svcInsID) {
805+
return *conn.TransitGateway.ID, nil
806+
}
807+
}
808+
}
809+
return "", nil
810+
}
811+
812+
// GetTGConnectionVPC checks if the VPC subnet is attached to the provided Transit Gateway.
813+
func (c *Client) GetTGConnectionVPC(ctx context.Context, gatewayID string, vpcSubnetID string) (string, error) {
814+
conns, err := c.getTransitConnections(ctx, gatewayID)
815+
if err != nil {
816+
return "", err
817+
}
818+
for _, conn := range conns {
819+
if *conn.NetworkType == "vpc" && strings.Contains(*conn.NetworkID, vpcSubnetID) {
820+
return *conn.ID, nil
821+
}
822+
}
823+
return "", nil
824+
}
825+
826+
func (c *Client) getTransitGateways(ctx context.Context) ([]transitgatewayapisv1.TransitGateway, error) {
827+
var (
828+
listTransitGatewaysOptions *transitgatewayapisv1.ListTransitGatewaysOptions
829+
gatewayCollection *transitgatewayapisv1.TransitGatewayCollection
830+
response *core.DetailedResponse
831+
err error
832+
perPage int64 = 32
833+
moreData = true
834+
)
835+
836+
listTransitGatewaysOptions = c.transitGatewayAPI.NewListTransitGatewaysOptions()
837+
listTransitGatewaysOptions.Limit = &perPage
838+
839+
result := []transitgatewayapisv1.TransitGateway{}
840+
841+
for moreData {
842+
// https://github.com/IBM/networking-go-sdk/blob/master/transitgatewayapisv1/transit_gateway_apis_v1.go#L184
843+
gatewayCollection, response, err = c.transitGatewayAPI.ListTransitGatewaysWithContext(ctx, listTransitGatewaysOptions)
844+
if err != nil {
845+
return nil, fmt.Errorf("failed to list transit gateways: %w and the respose is: %s", err, response)
846+
}
847+
848+
result = append(result, gatewayCollection.TransitGateways...)
849+
850+
if gatewayCollection.Next != nil {
851+
listTransitGatewaysOptions.SetStart(*gatewayCollection.Next.Start)
852+
}
853+
854+
moreData = gatewayCollection.Next != nil
855+
}
856+
857+
return result, nil
858+
}
859+
860+
func (c *Client) getTransitConnections(ctx context.Context, tgID string) ([]transitgatewayapisv1.TransitConnection, error) {
861+
var (
862+
listConnectionsOptions *transitgatewayapisv1.ListConnectionsOptions
863+
connectionCollection *transitgatewayapisv1.TransitConnectionCollection
864+
response *core.DetailedResponse
865+
err error
866+
perPage int64 = 32
867+
moreData = true
868+
)
869+
870+
listConnectionsOptions = c.transitGatewayAPI.NewListConnectionsOptions()
871+
listConnectionsOptions.Limit = &perPage
872+
873+
result := []transitgatewayapisv1.TransitConnection{}
874+
875+
for moreData {
876+
connectionCollection, response, err = c.transitGatewayAPI.ListConnectionsWithContext(ctx, listConnectionsOptions)
877+
if err != nil {
878+
return nil, fmt.Errorf("failed to list transit gateways: %w and the respose is: %s", err, response)
879+
}
880+
881+
result = append(result, connectionCollection.Connections...)
882+
883+
if connectionCollection.Next != nil {
884+
listConnectionsOptions.SetStart(*connectionCollection.Next.Start)
885+
}
886+
887+
moreData = connectionCollection.Next != nil
888+
}
889+
890+
return result, nil
891+
}

0 commit comments

Comments
 (0)